큐 포인트 및 메타데이터 사용

Flash Player 9 이상, Adobe AIR 1.0 이상

비디오를 재생할 때 NetStream 콜백 메서드를 사용하여 큐 포인트 및 메타데이터 이벤트를 캡처하고 처리할 수 있습니다.

큐 포인트 사용

다음 표에서는 Flash Player 및 AIR에서 F4V 및 FLV 큐 포인트를 캡처하는 데 사용할 수 있는 콜백 메서드를 설명합니다.

런타임

F4V

FLV

Flash Player 9/AIR1.0

 

OnCuePoint

   

OnMetaData

Flash Player 10

 

OnCuePoint

 

OnMetaData

OnMetaData

 

OnXMPData

OnXMPData

다음 예제에서는 간단한 for..in 루프를 사용하여 onCuePoint() 함수가 수신하는 infoObject 매개 변수의 각 속성을 반복합니다. 이 예제에서는 큐 포인트 데이터를 수신할 때 trace() 함수를 호출하여 메시지를 표시합니다.

var nc:NetConnection = new NetConnection(); 
nc.connect(null); 
 
var ns:NetStream = new NetStream(nc); 
ns.client = this; 
ns.play("video.flv"); 
 
var vid:Video = new Video(); 
vid.attachNetStream(ns); 
addChild(vid); 
 
function onCuePoint(infoObject:Object):void 
{ 
    var key:String; 
    for (key in infoObject) 
    { 
        trace(key + ": " + infoObject[key]); 
    } 
}

다음이 출력됩니다.

parameters:  
name: point1 
time: 0.418 
type: navigation

이 코드에서는 여러 방법 중 한 가지를 사용하여 콜백 메서드가 실행되는 객체를 설정했지만 다른 방법을 사용할 수도 있습니다. 자세한 내용은 메타데이터 및 큐 포인트에 대한 콜백 메서드 작성을 참조하십시오.

비디오 메타데이터 사용

OnMetaData()OnXMPData() 함수를 사용하여 큐 포인트가 들어 있는 비디오 파일의 메타데이터 정보에 액세스할 수 있습니다.

OnMetaData() 사용

메타데이터에는 지속 기간, 폭, 높이 및 프레임 속도와 같은 비디오 파일에 대한 정보가 포함됩니다. 비디오 파일에 추가되는 메타데이터 정보는 비디오 파일을 인코딩하는 데 사용하는 소프트웨어에 따라 다릅니다.

var nc:NetConnection = new NetConnection(); 
nc.connect(null); 
 
var ns:NetStream = new NetStream(nc); 
ns.client = this; 
ns.play("video.flv"); 
 
var vid:Video = new Video(); 
vid.attachNetStream(ns); 
addChild(vid); 
 
function onMetaData(infoObject:Object):void 
{ 
    var key:String; 
    for (key in infoObject) 
    { 
        trace(key + ": " + infoObject[key]); 
    } 
}

이전 코드에서는 다음을 출력합니다.

width: 320 
audiodelay: 0.038 
canSeekToEnd: true 
height: 213 
cuePoints: ,, 
audiodatarate: 96 
duration: 16.334 
videodatarate: 400 
framerate: 15 
videocodecid: 4 
audiocodecid: 2
비디오에 오디오가 포함되지 않은 경우에는 인코딩 중에 메타데이터에 추가되는 오디오 정보가 없으므로 오디오 관련 메타데이터 정보(예: audiodatarate)가 undefined를 반환합니다.

위의 코드에서는 큐 포인트 정보가 표시되지 않았습니다. 큐 포인트 메타데이터를 표시하려면 Object에서 항목을 반복적으로 표시하는 다음과 같은 함수를 사용합니다.

function traceObject(obj:Object, indent:uint = 0):void 
{ 
    var indentString:String = ""; 
    var i:uint; 
    var prop:String; 
    var val:*; 
    for (i = 0; i < indent; i++) 
    { 
        indentString += "\t"; 
    } 
    for (prop in obj) 
    { 
        val = obj[prop]; 
        if (typeof(val) == "object") 
        { 
            trace(indentString + " " + prop + ": [Object]"); 
            traceObject(val, indent + 1); 
        } 
        else 
        { 
            trace(indentString + " " + prop + ": " + val); 
        } 
    } 
}

앞의 코드 예제를 사용하여 onMetaData() 메서드의 infoObject 매개 변수를 추적하면 다음이 출력됩니다.

width: 320 
audiodatarate: 96 
audiocodecid: 2 
videocodecid: 4 
videodatarate: 400 
canSeekToEnd: true 
duration: 16.334 
audiodelay: 0.038 
height: 213 
framerate: 15 
cuePoints: [Object] 
    0: [Object] 
        parameters: [Object] 
            lights: beginning 
        name: point1 
        time: 0.418 
        type: navigation 
    1: [Object] 
        parameters: [Object] 
            lights: middle 
        name: point2 
        time: 7.748 
        type: navigation 
    2: [Object] 
        parameters: [Object] 
            lights: end 
        name: point3 
        time: 16.02 
        type: navigation

다음 예제에서는 MP4 비디오에 대한 메타데이터를 표시합니다. 이 예제에서는 메타데이터를 쓰는 대상으로 metaDataOut이라는 TextArea 객체가 있다고 가정합니다.

package 
{ 
    import flash.net.NetConnection; 
    import flash.net.NetStream; 
    import flash.events.NetStatusEvent; 
    import flash.media.Video; 
    import flash.display.StageDisplayState; 
    import flash.display.Loader; 
    import flash.display.Sprite; 
    import flash.events.MouseEvent; 
     
    public class onMetaDataExample extends Sprite 
    {     
        var video:Video = new Video(); 
         
        public function onMetaDataExample():void 
        { 
            var videoConnection:NetConnection = new NetConnection(); 
            videoConnection.connect(null); 
             
            var videoStream:NetStream = new NetStream(videoConnection); 
            videoStream.client = this; 
             
            addChild(video); 
            video.x = 185; 
            video.y = 5; 
                     
            video.attachNetStream(videoStream); 
             
            videoStream.play("video.mp4"); 
                         
            videoStream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); 
        } 
                     
        public function onMetaData(infoObject:Object):void 
        { 
            for(var propName:String in infoObject) 
            { 
                metaDataOut.appendText(propName + "=" + infoObject[propName] + "\n"); 
            } 
        } 
         
        private function netStatusHandler(event:NetStatusEvent):void 
        { 
            if(event.info.code == "NetStream.Play.Stop") 
                stage.displayState = StageDisplayState.NORMAL; 
        } 
    } 
}

onMetaData() 함수는 이 비디오에 대해 다음과 같은 출력을 생성합니다.

moovposition=731965 
height=352 
avclevel=21 
videocodecid=avc1 
duration=2.36 
width=704 
videoframerate=25 
avcprofile=88 
trackinfo=[object Object]

정보 객체 사용

다음 표에서는 수신하는 Object의 onMetaData() 콜백 함수에 전달되는 비디오 메타데이터로 가능한 값을 보여 줍니다.

매개 변수

설명

aacaot

AAC 오디오 객체 유형으로, 0, 1 또는 2가 지원됩니다.

avclevel

10, 11, 20, 21 등의 AVC IDC 레벨 번호입니다.

avcprofile

55, 77, 100 등의 AVC 프로파일 번호입니다.

audiocodecid

사용된 오디오 코덱(코딩/디코딩 기술)을 나타내는 문자열(예: ".Mp3", "mp4a")입니다.

audiodatarate

오디오가 인코딩된 속도(초당 킬로바이트)를 나타내는 숫자입니다.

audiodelay

FLV 파일에서 원본 FLV 파일의 "time 0"이 있는 시간을 나타내는 숫자입니다. 비디오 내용은 오디오를 정확하게 동기화할 약간의 시간 동안 지연되어야만 합니다.

canSeekToEnd

부울 값으로서, FLV 파일이 점진적 다운로드 비디오 파일의 끝까지 검색할 수 있도록 마지막 프레임의 키프레임으로 인코딩된 경우 true입니다. FLV 파일이 마지막 프레임의 키프레임으로 인코딩되지 않은 경우에는 false입니다.

cuePoints

객체 배열이며, 배열의 각 요소는 FLV 파일에 포함된 각 큐 포인트에 해당합니다. FLV 파일에 아무런 큐 포인트도 없으면 값은 정의되지 않습니다. 각 객체에는 다음과 같은 속성이 있습니다.

  • type: 큐 포인트의 유형을 "navigation" 또는 "event" 중 하나로 지정하는 문자열입니다.

  • name: 큐 포인트의 이름을 나타내는 문자열입니다.

  • time: 큐 포인트의 시간을 소수 세 자리(밀리초)까지 정밀하게 초 단위로 나타내는 숫자입니다.

  • parameters: 큐 포인트를 만들 때 사용자가 지정한 이름/값 쌍을 포함하는 객체이며, 선택 사항입니다.

duration

비디오 파일의 지속 시간을 초 단위로 지정하는 숫자입니다.

framerate

FLV 파일의 프레임 속도를 나타내는 숫자입니다.

height

FLV 파일의 높이를 픽셀 단위로 나타내는 숫자입니다.

seekpoints

사용 가능한 키프레임이 밀리초 단위의 타임스탬프로 나열되는 배열입니다. 선택 사항입니다.

tags

"ilst" 아톰의 정보를 나타내는 키-값 쌍의 배열이며 MP4 파일의 ID3 태그에 해당합니다. iTunes는 이러한 태그를 사용합니다. 사용 가능한 경우 아트웍을 표시하는 데 사용할 수 있습니다.

trackinfo

샘플 설명 ID를 비롯하여 MP4 파일의 모든 트랙에 대한 정보를 제공하는 객체입니다.

videocodecid

비디오 인코딩에 사용된 코덱 버전을 나타내는 문자열(예: "avc1", "VP6F")입니다.

videodatarate

FLV 파일의 비디오 데이터 속도를 나타내는 숫자입니다.

videoframerate

MP4 비디오의 프레임 속도입니다.

width

FLV 파일의 폭을 픽셀 단위로 나타내는 숫자입니다.

다음 표에서는 videocodecid 매개 변수로 가능한 값을 보여 줍니다.

videocodecid

코덱 이름

2

Sorenson H.263

3

스크린 비디오(SWF 버전 7 이상에서만 사용 가능)

4

VP6(SWF 버전 8 이상에서만 사용 가능)

5

알파 채널을 사용하는 VP6 비디오(SWF 버전 8 이상에서만 사용 가능)

다음 표에서는 audiocodecid 매개 변수로 가능한 값을 보여 줍니다.

audiocodecid

코덱 이름

0

압축되지 않음

1

ADPCM

2

Mp3

4

Nellymoser, 16kHz 모노

5

Nellymoser, 8kHz 모노

6

Nellymoser

10

AAC

11

Speex

onXMPData() 사용

onXMPData() 콜백 함수는 Adobe F4V 또는 FLV 비디오 파일에 포함된 Adobe XMP(Extensible Metadata Platform)와 관련된 정보를 수신합니다. XMP 메타데이터에는 큐 포인트와 그 밖의 비디오 메타데이터가 들어 있습니다. XMP 메타데이터는 Flash Player 10 및 Adobe AIR 1.5부터 도입되었으며 후속 버전에서 지원됩니다.

다음 예제에서는 XMP 메타데이터의 큐 포인트 데이터를 처리합니다.

package 
{ 
    import flash.display.*; 
    import flash.net.*; 
    import flash.events.NetStatusEvent; 
    import flash.media.Video; 
     
    public class onXMPDataExample extends Sprite 
    { 
        public function onXMPDataExample():void 
        { 
            var videoConnection:NetConnection = new NetConnection(); 
            videoConnection.connect(null); 
             
            var videoStream:NetStream = new NetStream(videoConnection); 
            videoStream.client = this; 
            var video:Video = new Video(); 
             
            addChild(video); 
             
            video.attachNetStream(videoStream); 
             
            videoStream.play("video.f4v"); 
        } 
         
        public function onMetaData(info:Object):void { 
            trace("onMetaData fired"); 
        } 
         
        public function onXMPData(infoObject:Object):void 
        { 
            trace("onXMPData Fired\n"); 
             //trace("raw XMP =\n"); 
             //trace(infoObject.data); 
            var cuePoints:Array = new Array(); 
            var cuePoint:Object; 
            var strFrameRate:String; 
            var nTracksFrameRate:Number; 
            var strTracks:String = ""; 
            var onXMPXML = new XML(infoObject.data); 
            // Set up namespaces to make referencing easier 
            var xmpDM:Namespace = new Namespace("http://ns.adobe.com/xmp/1.0/DynamicMedia/"); 
            var rdf:Namespace = new Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#"); 
            for each (var it:XML in onXMPXML..xmpDM::Tracks) 
            { 
                 var strTrackName:String = it.rdf::Bag.rdf::li.rdf::Description.@xmpDM::trackName; 
                 var strFrameRateXML:String = it.rdf::Bag.rdf::li.rdf::Description.@xmpDM::frameRate; 
                 strFrameRate = strFrameRateXML.substr(1,strFrameRateXML.length); 
                 
                 nTracksFrameRate = Number(strFrameRate);  
                 
                 strTracks += it; 
            } 
            var onXMPTracksXML:XML = new XML(strTracks); 
            var strCuepoints:String = ""; 
            for each (var item:XML in onXMPTracksXML..xmpDM::markers) 
            { 
                strCuepoints += item; 
            } 
            trace(strCuepoints); 
        } 
    } 
}

이 예제에서는 startrekintro.f4v라는 짧은 비디오 파일에 대해 다음과 같은 추적 행을 생성합니다. 이 행에서는 내비게이션용 큐 포인트 데이터와 XMP 메타데이터의 이벤트 큐 포인트를 보여 줍니다.

onMetaData fired 
onXMPData Fired 
 
<xmpDM:markers xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpDM="http://ns.adobe.com/xmp/1.0/DynamicMedia/" xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:x="adobe:ns:meta/"> 
  <rdf:Seq> 
    <rdf:li> 
      <rdf:Description xmpDM:startTime="7695905817600" xmpDM:name="Title1" xmpDM:type="FLVCuePoint" xmpDM:cuePointType="Navigation"> 
        <xmpDM:cuePointParams> 
          <rdf:Seq> 
            <rdf:li xmpDM:key="Title" xmpDM:value="Star Trek"/> 
            <rdf:li xmpDM:key="Color" xmpDM:value="Blue"/> 
          </rdf:Seq> 
        </xmpDM:cuePointParams> 
      </rdf:Description> 
    </rdf:li> 
    <rdf:li> 
      <rdf:Description xmpDM:startTime="10289459980800" xmpDM:name="Title2" xmpDM:type="FLVCuePoint" xmpDM:cuePointType="Event"> 
        <xmpDM:cuePointParams> 
          <rdf:Seq> 
            <rdf:li xmpDM:key="William Shatner" xmpDM:value="First Star"/> 
            <rdf:li xmpDM:key="Color" xmpDM:value="Light Blue"/> 
          </rdf:Seq> 
        </xmpDM:cuePointParams> 
      </rdf:Description> 
    </rdf:li> 
  </rdf:Seq> 
</xmpDM:markers> 
onMetaData fired
참고: XMP 데이터에서 시간은 초가 아니라 DVA 틱 수로 저장됩니다. 큐 포인트 시간을 계산하려면 시작 시간을 프레임 속도로 나눕니다. 예를 들어 시작 시간 7695905817600을 프레임 속도 254016000000으로 나누면 30:30이 됩니다.

프레임 속도가 포함된 전체 원시 XMP 메타데이터를 보려면 onXMPData() 함수의 시작 부분에서 두 번째 및 세 번째 trace() 문 앞의 주석 식별자(//)를 제거합니다.

XMP에 대한 자세한 내용은 다음을 참조하십시오.

이미지 메타데이터 사용

onImageData 이벤트는 AMF0 데이터 채널을 통해 이미지 데이터를 바이트 배열로 보냅니다. 데이터는 JPEG, PNG 또는 GIF 형식일 수 있습니다. onCuePointonMetaData에 대한 콜백 메서드를 정의할 때와 동일한 방법으로 onImageData() 콜백 메서드를 정의하여 이 정보를 처리할 수 있습니다. 다음 예제에서는 onImageData() 콜백 메서드를 사용하여 이미지 데이터에 액세스하고 이를 표시합니다.

public function onImageData(imageData:Object):void 
{ 
    // display track number 
    trace(imageData.trackid); 
    var loader:Loader = new Loader(); 
    //imageData.data is a ByteArray object 
    loader.loadBytes(imageData.data); 
    addChild(loader); 
} 

텍스트 메타데이터 사용

onTextData 이벤트는 AMF0 데이터 채널을 통해 텍스트 데이터를 보냅니다. 텍스트 데이터는 UTF-8 형식이며 3GP Timed-Text 사양을 기반으로 하는 형식에 대한 정보를 포함합니다. 이 사양은 표준화된 부제 형식을 정의합니다. onCuePoint 또는 onMetaData에 대한 콜백 메서드를 정의할 때와 동일한 방법으로 onTextData() 콜백 메서드를 정의하여 이 정보를 처리할 수 있습니다. 다음 예제에서 onTextData() 메서드는 트랙 ID 번호와 해당 트랙 텍스트를 표시합니다.

public function onTextData(textData:Object):void 
{ 
    // display the track number 
    trace(textData.trackid); 
    // displays the text, which can be a null string, indicating old text 
    // that should be erased 
    trace(textData.text); 
}