서버구축,나스구축,서버관리,윈도우서버,리눅스서버,서버관리

Posted
Filed under 프로그래밍/Html

<meta name="Subject" content=""> //홈페이지 주제
<meta name="Title" content=""> //제목
<meta name="Keywords" content=""> //키워드
<meta name="Description" content=""> //요약설명
<meta name="Author" content=""> //제작자
<meta name="Publisher" content=""> //제작사
<meta name="Other Agent" content=""> //웹책임자
<meta name="Claasification" content=""> //카테고리위치,분류
<meta name="Generator" content=""> //제작도구
<meta name="Reply-To" content=""> //메일주소
<meta name="Email" content=""> //메일주소
<meta name="Filename" content=""> //파일이름
<meta name="Author-Date" content=""> //제작일
<meta name="Date" content=""> //제작일
<meta name="Location" content=""> //위치
<meta name="Distribution" content=""> //배포자
<meta name="Copyright" content=""> //저작권
<meta name="Robots" content="ALL">
<meta name="Robots" content="index,follow"> //이 문서도 긁어가고 링크된 문서도 긁어감
<meta name="Robots" content="noindex,follow"> //이 문서는 긁어가지 말고 링크된 문서만 긁어감
<meta name="Robots" content="index,nofollow"> //이 문서는 긁어가고 링크는 무시함
<meta name="Robots" content="noindex,nofollow"> //이 문서도 긁지 않고 링크도 무시함
<meta http-equiv="X-UA-Compatible" content="IE=edge" />    <!--현재 웹페이지를 보고있는 ie버전의 엔진을 사용-->
<meta name="GOOGLEBOT" content="INDEX, FOLLOW">   //구글봇이 처리하는거

 

<meta http-equiv="Content-Type" content="text/html; charset=euc-kr"> //웹문서 언어 설정
<meta http-equiv="Imagetoolbar" content="no"> //그림위에 마우스 오버시 이미지 관련 툴바 숨김
<meta http-equiv="Refresh" content="60"> //60초 마다 새로고침
<meta http-equiv="Refresh" ccontent="5;url=주소"gt; //주소로 5초후 이동
<meta http-equiv="Cash-Control" content="no-cache"> //캐쉬가 되지 않게
<meta http-equiv="Last-Modified" content="Mon,20 Jul 2008 19:30:30"> //최종 수정일
<meta http-equiv="Pragma" content="no-cache"> //캐쉬가 되지 않게
<meta http-equiv="Expires" content="Mon, 08 Sep 2003 10:10:10 GMT">"> //캐쉬 만료(파기)일


<meta http-equiv="Page-Enter" content="revealtrans(Duration=1,Transition=12)">

//페이지 들어갈때 트랜지션 효과(장면 전환 효과)
<meta http-equiv="Page-Exit" content="revealtrans(Duration=1,Transition=12)">

//페이지 나갈때 트랜지션 효과(장면 전환 효과)

 

2015/04/15 11:42 2015/04/15 11:42
Posted
Filed under SERVER-OS/리눅스
Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 524288 bytes) in /home/Excel/reader.php on line 1008

 

라는 오류가 발생했다

 

처음에 단순하게 해당 파일 업로드 용량 과부하라 생각해서

 

서버에 php.in 파일의 max_file_uploads 설정용량을 변경했지만

또 에러가 났다 ㅠㅠ

 

그래서 찾아본결과 용량초과가 아닌 메모리 초과 였다

조금 더 생각해보면 알수 있었는데

왜냐고 용량은 10M 설정해놓고 엑셀파일은 4메가였으니까....

 

그레서 메모리 용량을 늘려주는 방법이 있다

1) php.in 파일에 memory_limit 용량을 변경 하는 법

 

2) 해당 오류난 위치 나 같은 경우는 on line 1008

즉 1008라인 바로 아래쪽에

ini_set('memory_limit', -1); 

이란 코드를 삽입하는것

 

2번째꺼가 제일 편하고 좋다 ㅎ

 

오류해결끝~

2015/04/15 11:39 2015/04/15 11:39
Posted
Filed under SERVER-OS/리눅스

근래의 메일서버는 간단한 설정이 가능한 postfix를 사용한다.

이를 이용해 메일서버를 설치하고 구글의 SMTP를 이용해 메일을 보내는 방법에 대해 알아보자

 

 

필요한 패키지 설치

 

# 메일 테스트를 위한 패키지 및 인증도구들 설치

# 일부는 이미 설치되어 있을수도...

$ sudo apt-get install mailutils libsasl2-2 ca-certificates libsasl2-modules

 

# Postfix 메일서버 설치

# 설치중에 몇가지 선택할 수 있는데 Internet Site 선택, mail.example.com과 같이 자신의 도메인을 설정

$ sudo apt-get install postfix

 

 

Postfix 설정

 

# Postfix 설정

$ sudo vi /etc/postfix/main.cf

 

# 아래의 내용을 하단에 붙여넣기

relayhost = [smtp.gmail.com]:587

smtp_sasl_auth_enable = yes

smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

smtp_sasl_security_options = noanonymous

smtp_tls_CAfile = /etc/postfix/cacert.pem

smtp_use_tls = yes


# sasl_passwd 파일을 생성하고 이 파일에 gmail 계정과 패스워드를 생성

$ sudo vi /etc/postfix/sasl_passwd

 

# USERNAME@gmail.com:PASSWORD 부분에 자신의 Gmail 계정과 패스워드 입력

# 만일 구글앱스를 사용해 도메인을 이용중이면 @gmail.com 대신에 @도메인주소를 사용가능

[smtp.gmail.com]:587    USERNAME@gmail.com:PASSWORD

 

# 권한 변경 및 Postfix 설정 업데이트 

$ sudo chmod 400 /etc/postfix/sasl_passwd

$ sudo postmap /etc/postfix/sasl_passwd

 

# 인증서 오류를 회피하기 위해 아래의 명령어 실행 

$ cat /etc/ssl/certs/Thawte_Premium_Server_CA.pem | sudo tee -a /etc/postfix/cacert.pem

 

# Postfix 재시작

$ sudo /etc/init.d/postfix reload

 

 

Mail 테스트

 

# you@example.com에 메일을 보낼주소를 입력

$ echo "Test mail from postfix" | mail -s "Test Postfix" you@example.com

 

이렇게 메일을 보내게 되면 구글 계정의 메일로 발송한 것이 되어 보낸편지함에 이력이 남기도 한다.

다만 하루에 500통의 메일 전송제약이 있다.

 

참고 : http://rtcamp.com/wordpress-nginx/tutorials/linux/ubuntu-postfix-gmail-smtp/

 

 

Mail Aliases

 

시스템에서 발생할 수 잇는 여러가지 에러나 각종 메세지를 전달받고 싶은데 이를 시스템에서 확인하지 않고 다른 메일로 포워딩 시킬수 있다.

 

# root 유저에게 전달되는 메일들을 다른메일계정으로 받아보기

$ sudo vi /etc/aliases

root:   system@example.com

 

# Aliases DB를 재생성

$ sudo newaliases

 

 

문제 해결

 

도메인 uzuro.com을 사용하는데 postfix 설치시 설정하게 되는데 mydestination 값에 uzuro.com 이 설정되어 있었다. 이때 시스템의 로컬상에서 구글 SMTP를 이용해 메일을 보낼때 시스템의 로컬의 주소를 uzuro.com으로 인식하게 된다. 예를 들어 webmaster@uzuro.com 에게 시스템에서 메일 보낸다면 이는 시스템 계정중에 webmaster를 찾고 메일을 보낸다. 원하는 바는 네이버웍스나 구글앱스등에 설정한 곳으로 메일을 보내는 것이였는데 시스템상에서 벗어나질 않았다.

$ sudo vi /etc/postfix/main.cf 

mydestination 의 값중에 uzuro.com 부분을 삭제하니 더 이상 시스템 내부에서 메일계정을 찾지 않고 원한는데로 네이버웍스에 설정된 주소로 메일이 발송되었다. 

2015/04/14 14:37 2015/04/14 14:37
Posted
Filed under SERVER-OS/리눅스

 명령

 의미

apt-get update

패키지 목록 갱신

apt-get upgrade

모든 패키지 목록 최신 버전으로 업그레이드

apt-get install [패키지명]

패키지 설치

apt-get remove [패키지명]

패키지 삭제(설정파일 삭제하지 않음)

apt-get purge [패키지명]

패키지 삭제(설정파일도 같이 삭제)

apt-cache search [검색어]

'검색어'를 포함한 패키지 검색

apt-get -h 도움말

 

2015/04/14 14:33 2015/04/14 14:33
Posted
Filed under 프로그래밍/Html
웹 페이지에 HTML5 동영상 컨트롤 추가에 설명된 대로 HTML5 video 요소를 통해 웹 페이지에서 동영상 요소 사용을 시작합니다. JavaScript를 추가하면 프로그래밍 방식으로 사용자 지정 재생 컨트롤을 만들고 현재 재생 위치를 가져오고 설정하며 현재 동영상을 변경할 수 있습니다. 여기서는 video 개체를 제어하는 데 사용할 수 있는 몇 가지 기본 메서드 및 속성에 대해 살펴봅니다.

고유한 단추를 만들려면 어떻게 해야 하나요?

HTML5 video 요소에는 동영상 재생을 재생, 일시 중지 및 검색하는 고유한 기본 제공 컨트롤이 있습니다. 다음 예제에서는 playpause 메서드를 사용하여 동영상을 시작하고 중지하며, currentTime 속성을 사용하여 동영상을 검색하고, paused 속성을 사용하여 동영상 플레이어의 현재 재생 상태를 가져옵니다.

복사
<script type="text/javascript">

    function vidplay() {
       var video = document.getElementById("Video1");
       var button = document.getElementById("play");
       if (video.paused) {
          video.play();
          button.textContent = "||";
       } else {
          video.pause();
          button.textContent = ">";
       }
    }

    function restart() {
        var video = document.getElementById("Video1");
        video.currentTime = 0;
    }

    function skip(value) {
        var video = document.getElementById("Video1");
        video.currentTime += value;
    }      
</script>

</head>
<body>        

<video id="Video1" >
//  Replace these with your own video files. 
     <source src="demo.mp4" type="video/mp4" />
     <source src="demo.ogv" type="video/ogg" />
     HTML5 Video is required for this example. 
     <a href="demo.mp4">Download the video</a> file. 
</video>

<div id="buttonbar">
    <button id="restart" onclick="restart();">[]</button> 
    <button id="rew" onclick="skip(-10)">&lt;&lt;</button>
    <button id="play" onclick="vidplay()">&gt;</button>
    <button id="fastFwd" onclick="skip(10)">&gt;&gt;</button>
</div>         


이 예제에서는 HTML5 video 요소를 source 요소와 함께 사용하여 웹 페이지에서 플레이어 및 동영상 콘텐츠를 설정합니다. 동영상 요소에는 id 특성만 있어 단추 및 JavaScript 기능에 대한 재생 컨트롤을 유지합니다. 단추는 동영상의 재생/일시 중지, 앞뒤로 건너뛰기 및 다시 시작 컨트롤을 제공합니다.

재생일시 중지 단추이기도 합니다. 별도의 단추가 있는 것이 아니라 재생 단추의 텍스트가 기능을 반영하도록 변경됩니다. 재생 단추를 클릭하면 "vidplay()" 함수를 호출하여 paused 속성을 확인합니다. paused 속성은 동영상이 일시 중지되거나 방금 로드된 경우 true를 반환하고 동영상이 재생 중이면 false를 반환합니다. 동영상이 일시 중지되면 "vidplay()"에서 play 메서드를 호출하고 재생 단추의 innerHTML을 "일시 중지"에 대한 기호인 "||"로 변경합니다. 재생 단추를 클릭할 때 동영상이 재생 중이면 pause 메서드가 호출되고 innerHTML이 "재생"에 대한 기호인 ">"로 변경됩니다.

다시 시작("[]"), 뒤로("<<") 및 앞으로(>>) 단추는 모두 currentTime 속성을 사용합니다. currentTime 속성은 현재 재생 위치를 초 단위로 나타냅니다. 재생앞으로 단추는 "skip()" 함수를 호출합니다. "skip()" 함수는 현재 시간에서 10초를 더하거나 빼는 매개 변수를 사용합니다. currentTime을 0보다 작거나 동영상 기간보다 큰 값으로 설정하면 동영상 플레이어에서 해당 값을 동영상의 시작이나 끝으로 설정합니다. 다시 시작("[]") 단추는 "restart()" 함수를 호출하여 currentTime을 0으로 설정합니다.

이 형식을 재생할 수 있을까요?

JavaScript에서 사용할 형식을 확인하는 작업은 웹 페이지에 HTML5 동영상 컨트롤 추가에 표시된 대로 source 요소를 사용하는 경우보다 약간 더 복잡합니다. 그러나 동영상의 요소의 지원은 변경되지 않으므로 사용 가능한 지원을 확인한 후 나머지 검색 세션에 대해 형식을 가정할 수 있습니다.

브라우저의 형식 기능을 찾으려면 video 개체의 canPlayType 메서드를 사용합니다. canPlayType 메서드는 동영상 MIME 형식과 선택적인 코덱 매개 변수를 사용하고 "empty", "maybe" 또는 "probably"의 세 문자열 중 하나를 반환합니다.

복사
  if (myvideo.canPlayType) {
    // CanPlayType returns maybe, probably, or an empty string.
    var playMsg = myvideo.canPlayType('video/mp4; codecs="avc1.42E01E"');
    if ("" != playMsg) {
      msg.innerHTML += "mp4/H.264 is " + playMsg + " supported <br/>";
    }
    playMsg = myvideo.canPlayType('video/ogg; codecs="theora"');
    if ("" != playMsg) {
      msg.innerHTML += "ogg is " + playMsg + " supported<br/>";
    }
    playMsg = myvideo.canPlayType('video/webm; codecs="vp8, vorbis"');
    if ("" != playMsg) {
      msg.innerHTML += "webm is " + playMsg + " supported<br/>";
    }
  }
  else {
    msg.innerHTML += "no video support";
  }
}


"maybe"와 "probably"의 차이점은 canPlayType 메서드에 정보가 충분하지 않다는 것입니다. 예를 들어 코덱 매개 변수가 누락된 경우 메서드에서 mp4 지원에 대해 "maybe"를 반환할 수 있습니다. 이는 지원되지 않는 mp4 코덱이 있을 수 있기 때문입니다. 코덱 매개 변수는 mp4 파일의 보다 구체적인 버전으로 지원의 범위를 좁힙니다.

canPlayType 메서드가 반환하는 세 상태의 모호함으로 인해 브라우저에서 해당 파일 형식을 지원하는지 여부를 결정하기가 어려울 수 있습니다. 규칙은 아니지만 브라우저에서 "maybe"를 반환하는 경우 해당 형식을 지원할 수도 있습니다. 다음 문에서는 반환된 문자열이 "maybe" 또는 "probably"일 경우 부울 true를 반환하고 문자열이 비어 있으면 false를 반환합니다.

복사
var playMsg = myvideo.canPlayType('video/mp4; codecs="avc1.42E01E"');
if ("" != playMsg) {
  msg.innerHTML += "mp4/H.264 is " + playMsg + " supported <br/>";
}


이전 예제의 첫 번째 줄에서는 "video/mp4; codecs="avc1.42E01E"" 매개 변수를 사용하여 canPlayType 메서드를 호출합니다. 그런 다음 "if" 문에서 결과가 빈 문자열이 아닌 다른 값인지를 확인합니다. 그럴 경우 메시지와 해당 결과를 표시합니다.

다음 예제에서는 mp4, ogv 및 webm의 세 가지 동영상 형식을 테스트합니다.

복사
<!doctype html>
<html>
<head>
    <title>Using multiple file formats in JavaScript</title>
    <!-- Uncomment the following meta tag if you have issues rendering this page on an intranet site. -->    
    <!--  <meta http-equiv="X-UA-Compatible" content="IE=edge"/> --> 
</head>
<body>
  <h1>CanPlayType test for multiple files</h1>
    <div>The canPlayType method tests for specific video formats and codecs. <br />It returns probably, maybe, or an empty string (no support).</div> 
    <br />
    <div>
        <button onclick="checkVideoCompat();">
            Test for video format type
        </button>
    </div>
    <div id="display"> </div>

    <script type= "text/javascript">
      function checkVideoCompat() {
        var myvideo = document.createElement('video');
        var msg = document.getElementById("display");
        msg.innerHTML = "";
        if (myvideo.canPlayType) {
          // CanPlayType returns maybe, probably, or an empty string.
          var playMsg = myvideo.canPlayType('video/mp4; codecs="avc1.42E01E"');
          if ("" != playMsg) {
            msg.innerHTML += "mp4/H.264 is " + playMsg + " supported <br/>";
          }
          playMsg = myvideo.canPlayType('video/ogg; codecs="theora"');
          if ("" != playMsg) {
            msg.innerHTML += "ogg is " + playMsg + " supported<br/>";
          }
          playMsg = myvideo.canPlayType('video/webm; codecs="vp8, vorbis"');
          if ("" != playMsg) {
            msg.innerHTML += "webm is " + playMsg + " supported<br/>";
          }
        }
        else {
          msg.innerHTML += "no video support";
        }
      }
    </script>


</body>
</html>


Windows Internet Explorer에서 HTML5 요소 및 기능을 사용하는 경우 사용하는 기능을 테스트하는 것이 가장 좋습니다. 이 예제에서는 createElement 메서드를 사용하여 동영상 개체를 만듭니다. video 개체가 성공적으로 만들어진 경우 "if (myvideo.canPlayType)" 문에서 true가 반환되고 특정 파일 형식을 테스트하는 실행이 계속됩니다.

파일을 변경하려면 어떻게 할까요?

이전 예제에서는 코드의 HTML 부분에서 source 태그를 사용하여 동영상 원본 파일을 지정합니다. 둘 이상의 파일을 재생하려면 src 속성을 사용하여 동영상 파일의 URL을 JavaScript로 지정할 수 있습니다.

이 예제에서 src 속성은 텍스트 입력 필드의 값으로 설정됩니다. 호환되는 동영상 파일의 URL을 필드에 입력하거나 붙여 넣은 다음 로드 단추를 클릭합니다.

복사
<div id= "inputField" style="display:none;" >
    <input type="text" id="videoFile" value="http://ie.microsoft.com/testdrive/ieblog/2011/nov/pp4_blog_demo.mp4" />        
    <button id="loadVideo" >Load</button>
</div>


로드 단추를 클릭하면 "getVideo()" 함수가 입력 필드(URL)에서 값을 가져와 src 속성에 할당합니다. 그런 다음 "getVideo()" 함수에서 "재생" 단추에 대한 click 메서드를 호출하여 파일이 재생을 시작합니다.

복사
                //  load video file from input field
                function getVideo() {
                    var fileURL = document.getElementById("videoFile").value;  // get input field                    
                    if (fileURL != ""){
                       video.src = fileURL;
                       video.load();  // if HTML source element is used
                       document.getElementById("play").click();  // start play
                     } else {
                        errMessage("Enter a valid video URL");  // fail silently
                     }
                }


재생 단추를 클릭하면 "vidplay()" 함수를 호출하여 재생하거나 일시 중지합니다. 재생할 단일 파일만 원본 요소에 의해 설정된 이전 예제와 달리 "vidplay()"에서 먼저 src 속성을 확인합니다. 페이지가 처음 로드되는 경우처럼 비어 있으면 "getVideo()" 함수가 호출되어 텍스트 필드에서 URL을 로드합니다. "getVideo()"는 입력 필드에서 URL을 가져오고, load 동영상 메서드를 호출한 다음 파일을 재생하는 재생 단추의 클릭 이벤트를 발생시킵니다. 페이지에서 이미 동영상을 재생 중인 경우 새 파일을 입력 필드에 붙여 넣으면 로드 단추를 클릭하여 파일을 변경합니다.

복사
                 //  play video
                 function vidplay(evt) {
                    if (video.src == "") {  // on first run, src is empty, go get file
                        getVideo();
                    }
                    button = evt.target; //  get the button id to swap the text based on the state                                    
                    if (video.paused) {   // play the file, and display pause symbol
                       video.play();
                       button.textContent = "||";
                    } else {              // pause the file, and display play symbol  
                       video.pause();
                       button.textContent = ">";
                    }                                        
                }


다음 예제에서는 body 요소의 onload 이벤트를 사용하여 "init()" 함수를 호출하고 예제의 모든 기능을 캡슐화합니다.

복사
<script type="text/javascript">
    // Master function, encapsulates all functions
    function init() {
        var video = document.getElementById("Video1");                                               
        if (video.canPlayType) {   // tests that we have HTML5 video support
            // if successful, display buttons and set up events
            document.getElementById("buttonbar").style.display = "block";
            document.getElementById("inputField").style.display = "block";

            //  button events
            //  Play
            document.getElementById("play").addEventListener("click", vidplay, false);
            //  Restart
            document.getElementById("restart").addEventListener("click", function(){
                setTime(0);
             }, false);
            //  Skip backward 10 seconds
            document.getElementById("rew").addEventListener("click", function(){
                setTime(-10);                
            }, false);
            //  Skip forward 10 seconds
            document.getElementById("fwd").addEventListener("click", function(){
                setTime(10);
            }, false);                
            //  set src == latest video file URL
            document.getElementById("loadVideo").addEventListener("click", getVideo, false);
                            
            // fail with message 
            video.addEventListener("error", function(err) {
                errMessage(err);
            }, true);

            //  button helper functions 
            //  skip forward, backward, or restart
            function setTime(tValue) {
            //  if no video is loaded, this throws an exception 
                try {
                    if (tValue == 0) {
                        video.currentTime = tValue;
                    }
                    else {
                        video.currentTime += tValue;
                    }
                    
                 } catch (err) {
                     // errMessage(err) // show exception
                 errMessage("Video content might not be loaded");
                   }
         }
             //  play video
             function vidplay(evt) {
                if (video.src == "") {  // on first run, src is empty, go get file
                    getVideo();
                }
                button = evt.target; //  get the button id to swap the text based on the state                                    
                if (video.paused) {   // play the file, and display pause symbol
                   video.play();
                   button.textContent = "||";
                } else {              // pause the file, and display play symbol  
                   video.pause();
                   button.textContent = ">";
                }                                        
            }
            //  load video file from input field
            function getVideo() {
                var fileURL = document.getElementById("videoFile").value;  // get input field                    
                if (fileURL != ""){
                   video.src = fileURL;
                   video.load();  // if HTML source element is used
                   document.getElementById("play").click();  // start play
                 } else {
                    errMessage("Enter a valid video URL");  // fail silently
                 }
            }
            //  display an error message 
            function errMessage(msg) {
            // displays an error message for 5 seconds then clears it
                document.getElementById("errorMsg").textContent = msg;
                setTimeout("document.getElementById('errorMsg').textContent=''", 5000);
            }

        } // end of runtime
    }// end of master         
</script>

</head>
<body onload="init();">        

<video id="Video1" style="border: 1px solid blue;" height="240" width="320">      
     HTML5 Video is required for this example
</video>

<div id="buttonbar" style="display: none;")>
    <button id="restart" >[]</button> 
    <button id="rew" >&lt;&lt;</button>
    <button id="play">&gt;</button>
    <button id="fwd" >&gt;&gt;</button>
</div>     
<div id= "inputField" style="display:none;" >
    <input type="text" id="videoFile" value="http://ie.microsoft.com/testdrive/ieblog/2011/nov/pp4_blog_demo.mp4" />        
    <button id="loadVideo" >Load</button>
</div>
<div id="errorMsg" style="color:Red;" ></div>


이 예제에서는 JavaScript addEventListener 메서드를 사용하여 HTML의 각 button 요소에 대한 onclick 이벤트가 아닌 단추에 대해 클릭 처리기를 제공합니다. 되감기, 앞으로다시 시작 단추는 각각 "setTime()" 함수를 호출하여 전달된 값을 기반으로 currentTime 동영상 속성을 설정합니다. 재생 단추는 "vidplay()" 함수를 호출하여 파일을 재생합니다.

참고  

온라인 동영상 사이트에서 동영상 링크를 붙여 넣는 경우 실제 동영상 파일(.mp4, .ogv 또는 유사한 확장명 사용)인지 확인해야 합니다. 웹에는 테스트 동영상 파일 원본이 많지만 일부 웹 사이트에서는 파일에 대한 링크가 아니라 검색용 URL을 제공합니다.

잘못된 부분이 있으면 어떻게 하나요?

오류 없이 코드를 작성하기란 어려운 일입니다. 이 예제에는 오류를 방지하거나 파악하도록 설계된 영역이 포함되어 있습니다. 예제가 실행될 때 HTML5 동영상 지원이 없으면 단추가 표시되지 않습니다. 그러나 동영상이 지원되면 일부 작업에서 예외가 발생합니다. oncanplay 이벤트를 사용하여 동영상 콘텐츠가 로드될 때까지 단추를 사용할 수 없도록 하는 예제는 HTML5 동영상 이벤트 사용을 참조하세요.

예외를 발생시키는 한 가지 작업은 로드된 동영상이 없을 때 currentTime 속성을 설정하는 것입니다. 이전 예제에서 "setTime()" 함수 코드는 예외가 발생될 경우 오류 메시지를 표시하는 try/catch 블록에서 실행됩니다. 예제에서는 유용한 메시지가 표시되지만 대신 원시 예외 표시에 대한 설명을 제거할 수 있습니다.

복사
   //  skip forward, backward, or restart
   function setTime(tValue) {
   //  if no video is loaded, this throws an exception 
       try {
           if (tValue == 0) {
               video.currentTime = tValue;
           }
           else {
               video.currentTime += tValue;
           }
           
        } catch (err) {
            // errMessage(err) // show exception
        errMessage("Video content might not be loaded");
          }
}


참고  F12 개발자 도구를 사용하면 F12 도구 콘솔이나 스크립트 탭으로 메시지를 보내 디버깅할 코드의 특정 영역에서 다시 보고할 수 있습니다. 콘솔로 메시지를 보내면 alert 메서드 호출처럼 코드 실행이 중단되지 않습니다. JavaScript를 사용하여 Windows 스토어 앱을 만들 때 페이지를 디버깅하려면 Microsoft Visual Studio를 사용합니다. F12 도구 콘솔 사용에 대한 자세한 내용을 보려면 How to use the F12 Developer Tools을 참조하세요.

동영상 속성으로 수행할 수 있는 기타 작업

동영상 속성 playbackRate, volumemuted를 사용하면 사운드트랙의 재생 속도 컨트롤 및 볼륨 컨트롤을 추가할 수 있습니다. 다음 예제에서는 재생 속도를 늘리고 줄이는 단추를 추가하여 오래된 영화처럼 재생하거나 슬로우 모션으로 재생합니다. 또한 볼륨을 변경하거나 오디오 트랙을 완전히 음소거하는 단추도 있습니다.

복사
// volume buttons
document.getElementById("volDn").addEventListener("click", function () {
    setVol(-.1); // down by 10%
}, false);
document.getElementById("volUp").addEventListener("click", function () {
    setVol(.1);  // up by 10%
}, false);

// playback speed buttons
document.getElementById("slower").addEventListener("click", function () {
    video.playbackRate -= .25;
}, false);
document.getElementById("faster").addEventListener("click", function () {
    video.playbackRate += .25;
}, false);
document.getElementById("normal").addEventListener("click", function () {
    video.playbackRate = 1;
}, false);
document.getElementById("mute").addEventListener("click", function (evt) {
    if (video.muted) {
        video.muted = false;
        evt.target.innerHTML = "<img alt='volume on button' src='vol2.png' />"
    } else {
        video.muted = true;
        evt.target.innerHTML = "<img alt='volume off button' src='mute2.png' />"
    }
}, false);


playbackRate 속성은 기본 설정 1을 사용하여 동영상의 기본 또는 정상 재생 속도의 승수를 나타냅니다. 속성을 2로 설정하면 재생 속도가 두 배가 되고 0.5로 설정하면 절반 속도로 재생됩니다. playbackRate가 음수 값으로 설정되면 Windows Internet Explorer 9에서는 0으로 반올림되어 기본적으로 재생이 일시 중지됩니다. Internet Explorer 10에서 playbackRate에 음수 값을 설정하면 동영상이 반대로 재생됩니다. W3C 사양에서는 상한을 권장하지 않지만 Internet Explorer에서는 playbackRate를 최대 8배속 속도로 제한합니다.

volume 속성을 사용하면 동영상 사운드트랙의 볼륨을 제어할 수 있습니다. volume 속성은 0에서 1 사이의 부동 소수점 값을 사용합니다. volume 속성은 0에서 1 사이여야 합니다. 그렇지 않으면 예외가 발생합니다. 다음 예제에서는 예외를 발생시키지 않고 볼륨 속성을 설정하는 한 가지 방법을 보여 줍니다. 볼륨 함수에서는 전달된 값 1 또는 10%(양수 또는 음수)를 현재 볼륨에 추가합니다. 볼륨이 허용 범위 0-1 외부에 있으면 가장 가까운 허용된 값으로 설정되어 예외를 방지합니다.

복사
// change volume based on incoming value 
function setVol(value) {
    var vol = video.volume;
    vol += value;
    //  test for range 0 - 1 to avoid exceptions
    if (vol >= 0 && vol <= 1) {
        // if valid value, use it
        video.volume = vol;
    } else {
        // otherwise substitute a 0 or 1
        video.volume = (vol < 0) ? 0 : 1;                        
    }
}


muted 속성은 true로 설정되면 사운드트랙을 바로 음소거하거나 false로 설정되면 volume 속성에 설정된 볼륨 수준으로 사운드트랙을 복원합니다. 다음 예제에서는 muted 속성을 토글하고 단추에 표시되는 이미지를 전환하는 음소거 단추 이벤트 처리기를 보여 줍니다.

복사
document.getElementById("mute").addEventListener("click", function (evt) {
    if (video.muted) {
        video.muted = false;
        evt.target.innerHTML = "<img alt='volume on button' src='vol2.png' />"
    } else {
        video.muted = true;
        evt.target.innerHTML = "<img alt='volume off button' src='mute2.png' />"
    }
}, false);


다음은 이전의 모든 예제에 대한 전체 코드 목록입니다.

복사
<html >
  <head>
    <title>Full player example</title>
    <!-- Uncomment the following meta tag if you have issues rendering this page on an intranet or local site. -->    
    <!-- <meta http-equiv="X-UA-Compatible" content="IE=edge"/> -->

    <script type="text/javascript">
        function init() {        // Master function, encapsulates all functions
            var video = document.getElementById("Video1");                                               
            if (video.canPlayType) {   // tests that we have HTML5 video support
                // if successful, display buttons and set up events
                document.getElementById("buttonbar").style.display = "block";                
                document.getElementById("inputField").style.display = "block";

                // helper functions
                //  play video
                function vidplay(evt) {
                    if (video.src == "") {  // inital source load
                        getVideo();
                    }
                    button = evt.target; //  get the button id to swap the text based on the state                                    
                    if (video.paused) {   // play the file, and display pause symbol
                        video.play();
                        button.textContent = "||";
                    } else {              // pause the file, and display play symbol  
                        video.pause();
                        button.textContent = ">";
                    }
                }
                //  load video file from input field
                function getVideo() {
                    var fileURL = document.getElementById("videoFile").value;  // get input field                    
                    if (fileURL != "") {
                        video.src = fileURL;
                        video.load();  // if HTML source element is used
                        document.getElementById("play").click();  // start play
                    } else {
                        errMessage("Enter a valid video URL");  // fail silently
                    }
                }



                //  button helper functions 
                //  skip forward, backward, or restart
                function setTime(tValue) {
                //  if no video is loaded, this throws an exception 
                    try {
                        if (tValue == 0) {
                            video.currentTime = tValue;
                        }
                        else {
                            video.currentTime += tValue;
                        }
                        
                     } catch (err) {
                         // errMessage(err) // show exception
                     errMessage("Video content might not be loaded");
                       }
             }
                //  display an error message 
                function errMessage(msg) {
                // displays an error message for 5 seconds then clears it
                    document.getElementById("errorMsg").textContent = msg;
                    setTimeout("document.getElementById('errorMsg').textContent=''", 5000);
                }
                // change volume based on incoming value 
                function setVol(value) {
                    var vol = video.volume;
                    vol += value;
                    //  test for range 0 - 1 to avoid exceptions
                    if (vol >= 0 && vol <= 1) {
                        // if valid value, use it
                        video.volume = vol;
                    } else {
                        // otherwise substitute a 0 or 1
                        video.volume = (vol < 0) ? 0 : 1;                        
                    }
                }
                //  button events               
                //  Play
                document.getElementById("play").addEventListener("click", vidplay, false);
                //  Restart
                document.getElementById("restart").addEventListener("click", function () {
                    setTime(0);
                }, false);
                //  Skip backward 10 seconds
                document.getElementById("rew").addEventListener("click", function () {
                    setTime(-10);
                }, false);
                //  Skip forward 10 seconds
                document.getElementById("fwd").addEventListener("click", function () {
                    setTime(10);
                }, false);
                //  set src == latest video file URL
                document.getElementById("loadVideo").addEventListener("click", getVideo, false);

                // fail with message 
                video.addEventListener("error", function (err) {
                    errMessage(err);
                }, true);
                // volume buttons
                document.getElementById("volDn").addEventListener("click", function () {
                    setVol(-.1); // down by 10%
                }, false);
                document.getElementById("volUp").addEventListener("click", function () {
                    setVol(.1);  // up by 10%
                }, false);

                // playback speed buttons
                document.getElementById("slower").addEventListener("click", function () {
                    video.playbackRate -= .25;
                }, false);
                document.getElementById("faster").addEventListener("click", function () {
                    video.playbackRate += .25;
                }, false);
                document.getElementById("normal").addEventListener("click", function () {
                    video.playbackRate = 1;
                }, false);
                document.getElementById("mute").addEventListener("click", function (evt) {
                    if (video.muted) {
                        video.muted = false;
                        evt.target.innerHTML = "<img alt='volume on button' src='vol2.png' />"
                    } else {
                        video.muted = true;
                        evt.target.innerHTML = "<img alt='volume off button' src='mute2.png' />"
                    }
                }, false);
            } // end of runtime
        }// end of master         
    </script>
    
    </head>
    <body onload="init();" >        
    
    <video id="Video1" controls style="border: 1px solid blue;" height="240" width="320" title="video element">            
         HTML5 Video is required for this example
    </video>
    
    <div id="buttonbar" style="display: none;")>
        <button id="restart" title="Restart button">[]</button> 
        <button id="slower" title="Slower playback button">-</button> 
        <button id="rew" title="Rewind button" >&lt;&lt;</button>
        <button id="play" title="Play button">&gt;</button>
        <button id="fwd" title="Forward button" >&gt;&gt;</button>
        <button id="faster" title="Faster playback button">+</button>
        <button id="Button2" title="Mute button" ><img alt="Volume on button" src="vol2.png" /></button>     
        <br />
        <label>Playback </label>
            <label>Reset playback rate: </label><button id="normal" title="Reset playback rate button">=</button>    
        
        <label>  Volume </label>
            <button id="volDn"  title="Volume down button">-</button>
            <button id="volUp"  title="Volume up button">+</button>
            <button id="mute" title="Mute button" ><img alt="Volume on button" src="vol2.png" /></button>        
    </div>   
    <br/>  
    <div id= "inputField" style="display:none;" >
        <label>Type or paste a video URL: <br/>
        <input type="text" id="videoFile" style="width: 300px;"  title="video file input field" value="http://ie.microsoft.com/testdrive/ieblog/2011/nov/pp4_blog_demo.mp4" />        
        <button id="loadVideo" title="Load video button" >Load</button>
        </label>
    </div>
    <div title="Error message area" id="errorMsg" style="color:Red;"></div>  
    </body>
</html>


HTML5 동영상 이벤트에서는 이벤트를 사용하여 콘텐츠의 사용 가능 여부를 확인하는 방법, 동영상 재생 상태 및 동영상에서 현재 재생 위치를 모니터링하는 방법을 살펴봅니다.

2015/03/26 10:04 2015/03/26 10:04

서버구축,나스구축,서버관리,윈도우서버,리눅스서버,서버관리

Posted
Filed under 프로그래밍/Html

HTML5 video 요소를 사용하여 웹 페이지에 동영상 플레이어를 추가하는 가장 기본적인 방법은 한 줄의 HTML로 수행됩니다. controls 특성을 추가하면 사용자가 동영상 재생을 제어할 수 있습니다. 다른 특성을 사용하여 원본 파일을 설정하거나 자리 표시자 이미지를 추가하거나 동영상 재생을 자동으로 시작할 수 있습니다. 대부분의 HTML 요소처럼 CSS 스타일시트를 사용하여 요소의 스타일과 위치를 지정할 수 있습니다.

HTML5 요소의 구문은 다음과 같습니다.

복사
<video src="demo.mp4" controls autoplay >HTML5 Video is required for this example</video> 


이 예에서는 한 줄의 코드에 대해 다양한 작업을 수행합니다. src 특성은 재생할 동영상 파일을 가리킵니다. src 특성은 동영상 요소에 대한 콘텐츠를 지정하는 두 가지 방법 중 하나를 제공합니다. 동영상을 재생하려면 비디오 파일의 URL에 src 특성을 할당합니다.

controls 특성은 브라우저에 기본 제공 재생 컨트롤을 표시하도록 지정합니다. 기본 제공 컨트롤의 기능과 모양은 브라우저마다 다를 수 있습니다. 최소한 재생일시 중지 컨트롤, 동영상에서 앞/뒤로 건너뛰는 단추 또는 진행률 표시줄, 시간 카운터가 표시되어야 합니다. 동영상을 재생하는 동안 컨트롤은 일반적으로 숨겨져 있으며, 마우스 커서를 플레이어 위로 이동하면 컨트롤이 다시 나타납니다.

autoplay는 동영상을 로드 후 바로 재생하도록 하는 부울 특성입니다.

동영상 요소에 사용할 수 있는 특성

동영상 요소는 동영상 재생 및 표시를 제어하는 많은 특성을 지원합니다. 이 표에서는 기본 동영상 특성에 대해 설명합니다. 부울 특성은 존재할 경우 "true"로 간주되고 video 요소의 특성으로 존재하지 않을 경우 "false"로 간주됩니다.

 

특성설명
src 동영상 파일을 가리키는 URL을 나타내는 문자열입니다.
controls 기본 제공 재생 컨트롤 집합을 설정하는 부울 특성입니다. 여기에는 일반적으로 재생, 일시 중지, 검색 및 볼륨 설정이 포함됩니다. Internet Explorer 10에는 여러 오디오 및 텍스트 트랙을 선택할 수 있는 컨트롤도 표시됩니다.
poster 동영상 플레이어에 표시되는 자리 표시자 이미지를 나타내는 문자열입니다. 해당 지점에 원본이 설정되어 있지 않거나 콘텐츠를 로드하는 중이어서 동영상을 사용할 수 없는 경우에만 포스터 이미지가 표시됩니다.
loop 컨트롤의 일시 중지 단추를 누르거나 스크립트에서 pause 메서드를 호출할 때까지 동영상을 반복적으로 재생하는 부울 특성입니다.
muted 오디오 트랙을 끈 상태로 동영상을 재생하는 부울 특성입니다.
autoplay 플레이어에서 콘텐츠를 충분히 버퍼링한 이후에 동영상 재생을 자동으로 시작하는 부울 특성입니다.
preload 얼마 만큼 버퍼링해야 하는지에 대한 힌트를 정의하는 부울 특성입니다.
height 동영상 플레이어의 높이(픽셀)를 설정합니다.
width 동영상 플레이어의 너비(픽셀)를 설정합니다.

 

참고  동영상 플레이어의 치수를 하나(예: 높이)만 설정하면 동영상 플레이어에서 해당 치수에 맞게 동영상 크기를 설정하고 비디오 콘텐츠의 가로 세로 비율을 기반으로 다른 치수를 조정합니다. 두 치수를 모두 동영상 콘텐츠와 일치하지 않는 가로 세로 비율로 설정하면 플레이어에서는 가로 세로 비율을 유지하면서 적합한 가장 근사한 치수로 배율을 조정합니다. 동영상은 한쪽에 공백을 두고 가로 또는 세로로 가운데에 배치됩니다.

다음 예에서는 동영상을 재생하고, 콘텐츠가 로드될 때까지 포스터를 표시하고, 재생 컨트롤이 있는 비디오를 반복적으로 재생합니다.

복사
<video src="demo.mp4" controls autoplay loop muted preload="auto" poster="demo.jpg" >
HTML5 Video is required for this example
</video> 


HTML의 동영상 요소에 대해 위의 특성을 설정할 수 있지만 JavaScript를 사용할 때 사용할 수 있는 많은 다른 옵션이 있습니다. 자세한 내용은 JavaScript를 사용하여 HTML5 동영상 플레이어 제어를 참조하세요.

여러 형식을 지원하는 방법

동영상 요소에서는 src 특성을 한 번에 하나만 설정할 수 있습니다. 파일 형식을 하나만 사용하려는 경우에는 문제가 되지 않습니다. 하지만 여러 파일 형식과 브라우저를 지원하려면 source 요소를 사용할 수 있습니다.

source 요소는 동영상 요소를 사용하여 동영상 콘텐츠 형식에 대한 "자동 맞춤"을 제공합니다. 즉, 여러 형식을 할당하면 HTML5 동영상 플레이어에서 가장 호환되는 형식을 자동으로 선택합니다. 대개 Windows Internet Explorer의 경우 .mp4 파일이 선택되고, 다른 브라우저의 경우에는 .ogg/.ogv 형식이 선택됩니다. 이 예에서는 다음과 같은 세 가지 파일 형식을 갖는 동영상 요소를 보여 줍니다.

복사
 <video controls poster="demo.jpg">
   <source src="demo.mp4" type="video/mp4" />
   <source src="demo.webm" type="video/webm"/>
   <source src="demo.ogv" type="video/ogg"/>             
   <p>Fallback code if video isn't supported</p>/
 </video>


이 예에는 — mp4, webm 및 ogg 동영상의 세 가지 형식이 나열됩니다. 브라우저에 따라 동영상 요소에서 재생 가능한 형식을 선택합니다. 아무 형식도 재생할 수 없거나 HTML5 동영상이 지원되지 않는 경우 작업이 완료되지 않고 video 태그 사이에 포함된 텍스트가 표시됩니다. 이 "대체" 동작을 사용하여 메시지를 표시하거나 포함된 플레이어를 추가할 수 있습니다.

이전 브라우저에서는 어떻게 됩니까?

플러그 인 또는 외부 플레이어 없이 웹 페이지에 동영상을 추가할 경우 새로운 Windows UI에서 Internet Explorer 9 또는 Internet Explorer 10을 실행 중인 사용자나 플러그 인을 지원하지 않는 모바일 장치 사용자에게는 문제가 되지 않지만, 지원하는 최신 브라우저를 사용 중인 사용자로 대상이 제한될 수 있습니다. 동영상 및 오디오 HTML5 요소를 사용하면 사용자 브라우저에서 HTML5를 지원하지 않는 경우에만 실행되는 태그 사이에 텍스트 또는 코드를 넣을 수 있습니다.

 

참고  오디오 및 동영상 요소는 두 요소가 지원되지 않는 경우에만 요소 사이의 코드가 실행되는 canvas와 다릅니다. Canvas에서는 태그 사이의 코드가 표시되지 않지만 canvas가 지원되는 경우에도 실제로 실행됩니다. 개발자는 Canvas Shadow DOM을 사용하여 화면 낭독 프로그램 및 다른 장치에 대한 접근성 지원을 제공할 수 있습니다. 자세한 내용은 HTML5 Canvas 및 Canvas Shadow DOM을 참조하세요.

다음 예는 Adobe Flash Player를 실행하여 이전 브라우저를 지원하도록 개체 태그를 추가한 점을 제외하고 마지막 예와 비슷합니다.

복사
 <video controls poster="demo.jpg">
   <source src="demo.mp4" type="video/mp4" />
   <source src="demo.webm" type="video/webm"/>
   <source src="demo.ogv" type="video/ogg"/>     
   <object>
     <embed src="demo.mp4" type= "application/x-shockwave-flash" allowfullscreen="false" allowscriptaccess="always" />
   </object>        
   HTML5 Video is required for this example
 </video>


이 예에서 브라우저는 HTML5 동영상을 지원할 경우 동영상 형식을 표시하려고 시도합니다. HTML5 동영상을 지원하지 않을 경우 개체 및 포함 태그를 사용하여 플래시 플레이어를 로드합니다.

다른 대체 옵션은 이 예에 표시된 것처럼 동영상 콘텐츠에 대한 링크만 제공합니다.

복사
HTML5 Video is required for this example. 
<a href="demo.mp4">Download the video</a> file. 


JavaScript를 사용하는 Windows 스토어 앱의 대체 기술에 대한 자세한 내용은 플러그 인 및 ActiveX 컨트롤을 참조하세요.

작은 스타일을 추가할 수 있나요?

HTML5 동영상 플레이어를 웹 페이지 디자인에 통합하도록 CSS를 사용하여 스타일 지정할 수 있습니다. heightwidth를 설정하고, 배경, 테두리position을 지정하고, CSS를 사용하여 동영상 요소의 visibility를 제어할 수 있습니다.

CSS의 z-index 속성을 사용하여 동영상 요소에 대해 이미지, 텍스트 또는 다른 동영상을 오버레이할 수 있습니다. 예를 들면 동일한 화면의 큰 동영상 위에 작은 비디오를 오버레이하는 PiP(화면 속 화면)가 있습니다.

화면 속 화면은 스포츠 이벤트의 다이어그램, 수화 통역사 등과 같은 관련 콘텐츠를 표시하는 데 주로 사용되는 기술입니다. 다음 예에서는 CSS를 사용하여 큰 동영상 위에 작은 비디오를 배치합니다. 또한 CSS를 사용하여 동영상 플레이어의 너비를 설정하고 삽입된 이미지 주위에 색이 지정된 테두리를 넣습니다.

복사
    <style type="text/css">       
    #Video1
    {
     position:absolute;
     top: 50px;
     left:0px;        
     width:1000px;       
     border:2px solid blue;
     display:block;
     z-index:99;
     }
        
   #Video2
    {
     position:absolute;
     top:80px;
     left:60px;
     width:300px;
     border:2px solid red;        
     z-index:100;
    }
    
    </style>
</head>
    <body>        
       <video id="Video1" controls loop autoplay >
           <source src="http://ie.microsoft.com/testdrive/ieblog/2011/nov/pp4_blog_demo.mp4" type="video/mp4" />           
       </video>
       
       <video id="Video2" muted autoplay controls >
           <source src="http://ie.microsoft.com/testdrive/Videos/BehindIE9AllAroundFast/video.mp4" type="video/mp4" />
           HTML5 Video not supported
       </video>             


z-index 속성을 사용하여 표시 순서를 변경할 수 있습니다. 일반적으로 웹 페이지의 요소는 만들어진 순서대로 표시됩니다. 한 요소가 다른 요소와 겹칠 경우 마지막에 렌더링된 요소가 완전히 표시됩니다. 최상위 요소인지 확인하려면 두 번째 동영상 프레임의 z-index를 100으로 설정합니다(비디오보다 먼저 만들어진 요소가 100개 미만이라고 가정). 두 번째 동영상 프레임은 재생 중인 비디오의 크기와 페이지에 있는 요소의 수를 기반으로 배치됩니다.

다른 CSS 속성을 사용할 수 있습니다. 예를 들어 transform을 사용하여 이미지를 회전하거나 borderRadius를 사용하여 다음 예에 표시된 것처럼 동영상 요소에 둥근 모서리를 만들 수 있습니다. 자세한 내용은 CSS 스타일시트 참조 페이지를 참조하세요.

복사
<html>
  <head>
    <title>Rotating a video</title>
    <style type="text/css">
   /* Set basic style for video */     
    #theVideo  
   {
        display:block;
        position:absolute;
        left:200px;
        top:200px;
        border: 2px solid red;
        border-radius: 20px;  
    }   
    /* Light up the image as a button, change cursor */
    #rotateVideo:hover
    {
        border:2px solid green;
        cursor: pointer;                
     }
        
    </style>
    <script>
        //  When the HTML elements load, call init()
        document.addEventListener("DOMContentLoaded", init, false);
       
        //  Rotate the video by 30degrees when image is clicked
        function init() {
          var video = document.getElementById("theVideo");
          if (video) {
            var rotateVal = 0;       //  Global variable to hold current rotation value
            document.getElementById("rotateVideo").addEventListener("click", function () {
              rotateVal = (rotateVal += 30) % 360;  // Calculate the next value, but keep between 0 and 360
              var temp = "rotate(" + rotateVal + "deg)"; // Create a style string
              document.getElementById("theVideo").style.msTransform = temp;  // Set the style
            }, false);
          }
        }
    </script>
   
  </head>
  <body>
    <img src="rotate.png" id="rotateVideo" alt="Rotate button" title="Click to rotate 30 degrees" role="button"/>
    <video src="http://ie.microsoft.com/testdrive/ieblog/2011/nov/pp4_blog_demo.mp4" id="theVideo" controls >
      This browser or mode doesn't support HTML5 video.
    </video>
  </body>
</html>


이동할 위치

여기서는 한 줄의 HTML을 사용하여 웹 페이지에 전체 기능을 갖춘 동영상 플레이어 컨트롤을 추가하는 방법에 대해 살펴보았습니다. 또한 전체 브라우저 지원을 위해 여러 동영상 형식을 지원하는 방법과 HTML5 동영상을 지원하지 않는 브라우저 지원을 위한 간단한 대체 예제를 살펴보았습니다.

2015/03/26 10:03 2015/03/26 10:03
Posted
Filed under 프로그래밍/MS-SQL
* Script 삽입 공격을 당했는지 확인하는 쿼리

DECLARE @T varchar(255), @C varchar(255);
DECLARE Table_Cursor CURSOR FOR
SELECT a.name, b.name
FROM sysobjects a, syscolumns b
WHERE a.id = b.id AND a.xtype = 'u' AND
(b.xtype = 99 OR
b.xtype = 35 OR
b.xtype = 231 OR
b.xtype = 167);
OPEN Table_Cursor;
FETCH NEXT FROM Table_Cursor INTO @T, @C;
WHILE (@@FETCH_STATUS = 0) BEGIN

exec ('select ['+@C+'] from ['+@T+'] where ['+@C+'] like ''%<script%</script>''');
-- print 'select ['+@C+'] from ['+@T+'] where ['+@C+'] like ''%<script%</script>'''

  FETCH NEXT FROM Table_Cursor INTO @T, @C;
END;
CLOSE Table_Cursor;
DEALLOCATE Table_Cursor;

* 위의 공격을 당했을 때 복원하는 쿼리 (100% 다 되는 것은 아님 - 별도 확인 필요)

* 해킹 시 길이가 긴 경우에는 짤리고 들어가는 현상이 발생함 - 이 경우에는 복원을 해도 원상복구가 안됨

* 백업 받은 것을 복원하는 수 밖에는 없음

DECLARE @T varchar(255), @C varchar(255);
DECLARE Table_Cursor CURSOR FOR
SELECT a.name, b.name
FROM sysobjects a, syscolumns b
WHERE a.id = b.id AND a.xtype = 'u' AND
(b.xtype = 99 OR
b.xtype = 35 OR
b.xtype = 231 OR
b.xtype = 167);
OPEN Table_Cursor;
FETCH NEXT FROM Table_Cursor INTO @T, @C;
WHILE (@@FETCH_STATUS = 0) BEGIN
  EXEC(
    'update ['+@T+'] set ['+@C+'] = left(
            convert(varchar(8000), ['+@C+']),
            len(convert(varchar(8000), ['+@C+'])) - 6 -
            patindex(''%tpircs<%'',
                      reverse(convert(varchar(8000), ['+@C+'])))
            )
      where ['+@C+'] like ''%<script%</script>'''
      );
  FETCH NEXT FROM Table_Cursor INTO @T, @C;
END;
CLOSE Table_Cursor;
DEALLOCATE Table_Cursor;


DB injection 공격?
구글에서 <script src= 0.js 라고 검색하면 놀랄 정도로 많은 사이트들이 DB 공격을 받았음을 확인 하실 수 있을겁니다.
제가 관리하는 사이트 또한 위와같은 스크립트 삽입되어 수많은 사이트를 찾아 다니며 복구하고 나름대로 보안하는 방법을 접하게 된 것을 올려 봅니다.


1. 공격 유형 :
SQL injection 홈페이지 상의 DB사용하는 페이지를 공격 즉, 웹소스 취약한 곳을 통해 DB를 공격.
특수 코드 삽입해서 DB에 스크립트를 삽입하여 접속하는 사용자에게 악성코드를 설치하는 유형.


2. 조치 시 주의 사항
1) 홈페이지 변조를 통해 악성코드 링크를 삽입한게 아니라, SQL injection 기법을 이용해 DB 컨텐츠에 삽입한 것입니다.
2) 조치 시 DBA 의 도움을 받는게 좋습니다.
3) 공격 때문에 기존의 데이터가 일부 덧씌워져 변경되었을 수 있습니다. 이럴 땐 백업의 도움을 받아야 겠지만, 일부 데이터의 유실은 어쩔 수 없을 듯...
4) 근본 원인은 사이트가 SQL injection 공격에 취약하게 개발되어 있어서 그렇습니다. 공격 포인트를 파악해서 외주개발 업체, 혹은 내부개발팀을 통해 소스를 수정하세요.
5) 소스를 수정할 수 없는 경우 웹 방화벽이 도움이 될 수도 있습니다. 그러나, 제품 도입시 면밀히 검토하실 필요가 있습니다. 단순 패턴 매칭 형태를 사용해서, 보유패턴과 1byte 만 틀려도 탐지 못하는 제품이 몇 개 있더군요.


3. 공격으로 생긴 DB table 삭제
comd_list 테이블 삭제
ahcmd 테이블 삭제
foofoofoo 테이블 삭제
Reg_Arrt 테이블 삭제
comd_list 테이블 삭제
D99_CMD 테이블 삭제
D99_TMP 테이블 삭제
Kill_kk 테이블 삭제
jiaozhu 테이블 삭제


4. 삽입 스크립트 제거 복구
DECLARE @T varchar(255), @C varchar(255);
DECLARE Table_Cursor CURSOR FOR
SELECT a.name, b.name
FROM sysobjects a, syscolumns b
WHERE a.id = b.id AND a.xtype = 'u' AND
(b.xtype = 99 OR
b.xtype<object id=sayboxtistorycom4534743 codeBase=http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0 height="100%" width="100%" classid=clsid:d27cdb6e-ae6d-11cf-96b8-444553540000> <object width="100%" height="100%" wmode="transparent" id="sayboxtistorycom4534743" src="http://cfs.tistory.com/blog/plugins/CallBack/callback.swf?destDocId=callbacknestsayboxtistorycom4534743&id=453&callbackId=sayboxtistorycom4534743&host=http://saybox.tistory.com&float=left&" allowScriptAccess="always" menu="false" type="application/x-shockwave-flash" ></object></object>= 35 OR
b.xtype = 231 OR
b.xtype = 167);
OPEN Table_Cursor;
FETCH NEXT FROM Table_Cursor INTO @T, @C;
WHILE (@@FETCH_STATUS = 0) BEGIN
  EXEC(
    'update ['+@T+'] set ['+@C+'] = left(
            convert(varchar(8000), ['+@C+']),
            len(convert(varchar(8000), ['+@C+'])) - 6 -
            patindex(''%tpircs<%'',
                      reverse(convert(varchar(8000), ['+@C+'])))
            )
      where ['+@C+'] like ''%<script src=http://s.ardoshanghai.com/s.js></script>'''
      );
  FETCH NEXT FROM Table_Cursor INTO @T, @C;
END;
CLOSE Table_Cursor;
DEALLOCATE Table_Cursor;

'스크립트 부분은 삽입된 스크립트를 입력


5. 보안 적용 1 - MSSQL 메모리에서 위험한 sp들을 내린다.
보안상 위협이 될 수 있는 개체들에 대하여 일반 사용자 그룹의 사용권한을 제한한다.
SP 등록해제는 위험을 감안해야 하므로 메모리에서만 내린다. 단점, 재부팅되거나 DB 재시작시 다시 아래 쿼리 실행 할것!

dbcc xp_cmdshell(free)
dbcc xp_dirtree(free)
dbcc xp_regdeletekey(free)
dbcc xp_regenumvalues(free)
dbcc xp_regread(free)
dbcc xp_regwrite(free)
dbcc sp_makewebtask(free)


6. 보안 적용 2
무엇보다 DB 인젝션이 발생한 원인인 로그인, 회원가입, 게시판 등 사용자가 DB를 접하게 되는 소스 개발시 특수 문자 보안 적용 안된 경우가 가장 유력하다.
로그인, 회원가입, 아이디 비번찾기, 게시판 등이 개발자가 개발하면서 DB를 공격할만한 특수 문자에 대한 차단 기능을 적용하지 않은 문제로 판단됨. 소스를 모두 개선 해야함.
2015/03/24 12:11 2015/03/24 12:11
Posted
Filed under 컴퓨터 상식

설치한 메일서버를 통해 발송되는 메일이
스팸으로 들어가는 경우가 더러 있다.

이게 한번 들어가기는 쉬운데,
빠져나오기는 드럽게 힘든것 같다...


본인의 경우에는
우선 국내서비스에는 무리 없이 들어간다. (naver,daum )
그런데 해외메일 그중 Gmail, Hotmail에는
에누리없이 스팸으로 간주되고 있었다.

Gmail
같은 경우에는 그래도 스팸함으로 발송은 제대로 되는반면에
Hotmail
같은경우에는 아예 수신자체가 안되는 경우도 더러있다.. ,.;

제일 좋은 방법은
Gmail,Hotmail
전화걸어서 우리 메일서버 IP white Ip 등록해달라!!!
하면 좋지만, 얘네들은 걸어봤자 자동응답기고,
문의채널은 구글 그룹스 게시판이 전부다..


본론으로 들어가서.
해외 메일이 차단될 경우
매일서버ip 스팸ip 등록되 버린 경우일 있다. (본인처럼. )
이것부터 조회 해보고 싶으면
RBL(real-time blocking List)
체크를 해야 하는데,
RBL
체크 해주는 사이트는 많이 있고,
그중 깔끔해 보이는곳 하나 소개.

http://www.anti-abuse.org/






메일서버ip 입력하고 조회해보면
쭈루룩 리스트가 나온다.
빨간불이 들어온 부분이
메일 서버가 스팸서버가 각종 이유들이다.

   

본인의 경우 CBL 때문에 걸렸는데,
내용은 아래와 같다
.


This IP address is HELO'ing as "localhost.localdomain" which violates the relevant standards (specifically: RFC5321).


메일서버 도메인에 별다른 작업을 안해놓아서
"localhost.localdomain"
으로 설정되어있었다.

만약 CBL 바로 테스트 해보고 싶으면
http://cbl.abuseat.org/lookup.cgi
여기서 해보면 다른 유무 상관없이 cbl 바로 있다.

그리고 결과에
is listed!!! 
라고 뜨면 당신의 메일서버는 당첨!!

바로 해제를 하려면
페이지 하단에
어쩌구 IP delist 저쩌구 
라는 링크가 나오는데
이부분만 클릭해 놓고 나면
몇시간 후에 ip
CBL
로부터 해제된다.

그러나!!

근본적인 원인을 해결하지 않으면
해제의 기쁨을 누린지 얼마 안되서 
다시 블럭 되버린다. ㅡㅡㅋ 


localhost.localdomain
수정하는 방법은 간단하다.
아래 파일 2 열어서 수정해주면 된다.

/etc/hosts
127.0.0.1  changmail.com localhost

/etc/sysconfig/network
...
HOSTNAME=changmail.com

그런데, 이런다고 바로 되는건 아니고,
메일서버가 스팸에서 풀리는데는 시간이 좀더 시간이 걸리는것 같다.


그리고 CBL 이외에도 많이 걸리는 이유 중에 하나가
메일서버의 reverse dns 설정이 안되어 있어서라고 한다.

nslookup -typ=ptr xxx.xxx.xxx.xxx(
서버ip)

쳤을때 서버주소 안나오고

** server can't find 71.106.170.211.in-addr.arpa: NXDOMAIN


이런식으로
나오면 등록이 안된거니까 이부분도 확인
해결 방법은 아래 링크 참조
http://passkorea.net/Board/ViewDoc.aspx?brdNo=8&docNo=29293


추가로 보험드는 기분으로
https://www.kisarbl.or.kr/
여기에서 화이트 도메인으로 등록해두자.

화이트 도메인 등록시에 2단계에서

현재 위 도메인의 DNS에는 등록이 불가능한 IP를 포함하여 SPF Record가 작성되어 있으므로, White Domain으로
등록할 수 없습니다. KISA 의 ' 통합 White Domain 리스트 ' 는 SPF 레코드를 기반으로 개별 도메인에 대한 신뢰도를
측정함으로써 관리/ 운영됩니다. DNS에 SPF Record를 정확하게 작성한 후 다시 등록하여 주시기 바랍니다.

   

이렇게 나오는 경우가 있다

당황하지 말고

ksrt@kisa.or.kr 문의 메일 넣으면 

의외로(?) 금방 답변을 주신다

   



그리고 이건 마무리하는 의미에서


구글에서 말하는 메일이 스팸으로 표시되는 이유
http://support.google.com/mail/bin/answer.py?hl=ko&ctx=mail&answer=1366858&expand=5

위에도 적혀있지만,
한번 걸리면 풀어지는데는 걸리나 보다.
아쉬운 마음에 사람들이
딱히 문의채널도 없어서 구글 그룹스에다가 ip 해제 해달라고 하는데,
간혹 달린 사람들 답변보면,
여기 적는다고 구글에서 풀어주진 않는다고 한다.
당신의 메일 서버가
google
대량메일 발신자 가이드라인에 적합하면
그때 자연스럽게 해제될 .

지들은 아무것도 안한덴다....

2015/03/06 09:45 2015/03/06 09:45

서버구축,나스구축,서버관리,윈도우서버,리눅스서버,서버관리

Posted
Filed under 컴퓨터 상식

유튜브 동영상을 보다가 보면 소장하고 싶은 동영상을 발견할 때가 있습니다.

이를 때 확장프로그램 설치 할 필요도 없고 웹브우져에 관계 없이 간단하게 동영상을 다운받은 수 있는 방법이 있어 소개합니다.

방법은 유튜브 주소창에 'SS'를 추가해 주고 그 주소로 이동하면 됩니다.

   

예)                   http://www.youtube.com/watch?v=-6Gdpb4q6jI

변경 후   =>      http://www.ssyoutube.com/watch?v=-6Gdpb4q6jI

그럼 아래와 비슷한 화면이 보일 것입니다.

빨간색 네모로 표시 된 곳에서 마음에 드는 화질로 다운 받으면 됩니다. 

그런데 익스플로는 다운 받을 때 확장명이 없는 동일한 파일로만 다운됩니다.

그렇기 때문에 다른 이름으로 저장을 눌러 파일명을 바꾼 후 확장자(.mp4)를 추가해 주어야 합니다.

익스플로러를 다운 받을 때 파일 이름을 변경해 주어야 한다는 단점이 있지만 간단하게 웹브라우져에 크게 상관 없이 간단하게 다운 받을 수 있어 편한 것 같습니다.

확장 프로그램을 설치하는 것을 싫어 한다면 한번 이용해 보세요.

2015/03/06 09:43 2015/03/06 09:43
Posted
Filed under 컴퓨터 상식

스마트폰이 필수품이라고 할 정도로 우리 생활에 깊숙이 자리 잡고 있죠.

그리고 그 스마트폰에 설치된 많은 어플 중에 카카오톡이 많은 자리를 차지하고 있습니다.

이유는 채팅을 하지 않아도 게임이나 다른 것을 할 때 인증 수단 

한 번씩 카카오톡 친구에게 문자를 보냅니다.

그런데 친구 중에 카톡을 잘 확인도 하지 않고 연락도 잘 하지 않는 친구를 볼 때면 마음이 답답하기도 하고 카톡을 차단했나 하는 생각까지 들 때가 있습니다. 이를 때 차단 확인 방법이라도 있으면 깝깝한 마음이 좀 풀릴 것 같기도 하지만 카카오톡에는 그런 방법을 지원해 주는 것 같지도 않고....

그러다 우연히 차단 확인 어플이 있다는 것을 알고 설치해 보았습니다. (차단 확인 어플 바로가기 )

어플을 설치하고 스마트폰 메뉴 버튼을 클릭하면 빨간색으로 표시한 메뉴가 보일 것입니다.

   

여기서 차단 확인 때 초대할 유령 친구를 먼저 추가해 줍니다.

'유령 친구 추가' 항목을 클릭하면 카카오톡 앱이 실행 될 것입니다.

여기서 설정 -> 친구 관리를 선택한 다음 자동 친구 추가를 체크해 줍니다.

그리고 동기화 버튼을 클릭하면 유령 친구 두 명이 추가된 것을 볼 수 있을 것입니다. 

그리고 다시 차단 확인 어플으로 가서 '카톡 차단 확인 하기' 항목을 클릭해 줍니다.

그럽 아래와 같이 카카오톡 대화 상대 선택 화면이 보일 것입니다.

앞에 추가한 유령 친구 두 명만 대화 상대로 선택해 줍니다.

그럼 유령 친구 두 명을 초대했다는 메세지와 함께 '친구 한 명을 초대해 차단되었는지 확인해 보세요'는 메세지가 보일 것입니다. 그럼 이제 차단 확인하고 싶은 친구를 추가해 주면 됩니다.

그리고 초대 메세지가 나타나는지 확인하고 조용히 채팅방을 나오면 됩니다.

그런데 유령 친구를 초대할 때 함께 차단 확인할 친구를 같이 초대하면 차단 확인은 가능하지만 앱에서 자동으로 작성하는 글이 친구에게도 보내져 찝찝할 수 있으니 주의하세요.

2015/03/06 09:42 2015/03/06 09:42