OSMF获取元数据

最近公司需要一款播放器,想着用用adobe官方的osmf。这个框架支持所有flash允许的视频格式,支持HDS,很少的代码就搞定,方便快捷,开发周期短。下了osm以及strobeMediaPlayBackf研究了一下,很好入手。但是当把播放器放到公司网站上发现,视频任一点快进功能没了(公司部署的是伪流服务,使用start =关键帧方式)。再实验,通过现有框架内容,竟然无法获取关键帧信息。懊恼!这么常见东东居然没有。HDS先进,可要银子。只要自己挖掘了。其实在读取视频的duration, width, height等信息的时候,osmf已经取到了视频的元数据信息。不知道是出于什么原因,osmf将keyframes忽略了。只好自己动手搞定。麻烦啊。好在弄出来了, 随便讲一下吧。首先学了一下osmf如何去视频的duration, 发现时在NetStreamTimeTrait中获取,并将NetStreamTimeTrait加入mediaElement中。照葫芦画瓢,弄了个KeyFramesTraits。

package org.osmf.traits
{
	import flash.net.NetStream;
	
	import org.osmf.events.KeyFramesEvent;
	import org.osmf.net.NetClient;
	import org.osmf.net.NetStreamCodes;
	
	[Event(name="keyFramesChange", type="org.osmf.events.KeyFramesEvent")]
	public class KeyFramesTraits extends MediaTraitBase
	{
		public static const KEY_FRAMES:String = "keyFrames";
		
		private var _keyFrames:Object;
		
		private var netStream:NetStream;
		
		public function KeyFramesTraits(netStream:NetStream)
		{
			super(KEY_FRAMES);
			this.netStream = netStream;
			NetClient(netStream.client).addHandler(NetStreamCodes.ON_META_DATA, onMetaData);
		}
		
		private function onMetaData(value:Object):void
		{
			if(!value)
				return;
			
			if(value["keyframes"])
			{
				_keyFrames = value["keyframes"];
			}
			else if(value["seekpoints"])
			{
				_keyFrames = value["seekpoints"];
			}
			else
			{
				_keyFrames = null;
			}
			
			dispatchEvent(new KeyFramesEvent(KeyFramesEvent.KEYFRAMES_CHANGE, false, false, _keyFrames));
		}
		
		public function get keyFrames():Object
		{
			return _keyFrames;
		}
			
	}
}

其中,dispatchevent了一个事件,如下:

package org.osmf.events
{
	import flash.events.Event;
	
	public class KeyFramesEvent extends Event
	{
		public static const KEYFRAMES_CHANGE:String = "keyFramesChange";
		
		public var _keyFrames:Object;
		
		public function KeyFramesEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false, keyFrames:Object = null)
		{
			super(type, bubbles, cancelable);
			_keyFrames = keyFrames;
		}
		
		private function get keyFrame():Object
		{
			return _keyFrames;
		}
		
		override public function clone():Event
		{
			return new KeyFramesEvent(type, bubbles, cancelable, keyFrame);
		}
	}
}


有了获取关键帧信息的类了,还要把他加入到mediaElement中去,关键帧只有视频才使用,所以扩展了一下videoElement。创建一个AdvancedVideoElement。

package org.osmf.elements
{
	import flash.net.NetStream;
	
	import org.osmf.events.KeyFramesEvent;
	import org.osmf.media.MediaResourceBase;
	import org.osmf.net.NetClient;
	import org.osmf.net.NetLoader;
	import org.osmf.net.NetStreamCodes;
	import org.osmf.net.NetStreamLoadTrait;
	import org.osmf.traits.KeyFramesTraits;
	import org.osmf.traits.MediaTraitBase;
	import org.osmf.traits.MediaTraitType;
	
	public class AdvancedVideoElement extends VideoElement
	{
		
		private var stream:NetStream;
		
		public function AdvancedVideoElement(resource:MediaResourceBase=null, loader:NetLoader=null)
		{
			super(resource, loader);
		}
		
		override protected function processReadyState():void
		{
			super.processReadyState();
			addKeyFramesTraits();
		}
		
		private function addKeyFramesTraits():void
		{
			var loadTrait:NetStreamLoadTrait = getTrait(MediaTraitType.LOAD) as NetStreamLoadTrait;
			stream = loadTrait.netStream;
			// setup dvr trait
			var keyFramesTrait:MediaTraitBase = loadTrait.getTrait(KeyFramesTraits.KEY_FRAMES) as KeyFramesTraits;
			if (keyFramesTrait == null)
			{
				keyFramesTrait = new KeyFramesTraits(stream);
			}
			
			keyFramesTrait.addEventListener(KeyFramesEvent.KEYFRAMES_CHANGE, onKeyFramesChange);
			
			function onKeyFramesChange(event:KeyFramesEvent = null):void
			{
				addTrait(KeyFramesTraits.KEY_FRAMES, keyFramesTrait);
			}
		}
		
	}
}


我们只要创建AdvancedVideoElement,其实就可以获取到keyframes了。osmf中DefaultMediaFactory可以帮助我们创建各种mediaElement,但是我们的AdvancedVideoElement还是不成的。而且扩展DefaultMediaFactory还不成。只要自己弄个facatory了。


package org.osmf.media
{
	import org.osmf.elements.AdvancedVideoElement;
	import org.osmf.elements.AudioElement;
	import org.osmf.elements.F4MElement;
	import org.osmf.elements.F4MLoader;
	import org.osmf.elements.ImageElement;
	import org.osmf.elements.ImageLoader;
	import org.osmf.elements.SWFElement;
	import org.osmf.elements.SWFLoader;
	import org.osmf.elements.SoundLoader;
	import org.osmf.elements.VideoElement;
	import org.osmf.net.NetLoader;
	import org.osmf.net.dvr.DVRCastNetLoader;
	import org.osmf.net.rtmpstreaming.RTMPDynamicStreamingNetLoader;
	
	CONFIG::FLASH_10_1
	{
		import org.osmf.net.httpstreaming.HTTPStreamingNetLoader;
		import org.osmf.net.MulticastNetLoader;
	}


	
	public class AdvancedMediaFactory extends MediaFactory
	{
		public function AdvancedMediaFactory()
		{
			super();
			init();
		}
		
		private function init():void
		{
			f4mLoader = new F4MLoader(this);
			addItem 
			( new MediaFactoryItem
				( "org.osmf.elements.f4m"
					, f4mLoader.canHandleResource
					, function():MediaElement
					{
						return new F4MElement(null, f4mLoader);
					}
				)
			);
			
			dvrCastLoader = new DVRCastNetLoader();
			addItem
			( new MediaFactoryItem
				( "org.osmf.elements.video.dvr.dvrcast"
					, dvrCastLoader.canHandleResource
					, function():MediaElement
					{
						return new VideoElement(null, dvrCastLoader);
					}
				)
			);
			
			CONFIG::FLASH_10_1
			{
				httpStreamingNetLoader = new HTTPStreamingNetLoader();
				addItem
				( new MediaFactoryItem
					( "org.osmf.elements.video.httpstreaming"
						, httpStreamingNetLoader.canHandleResource
						, function():MediaElement
						{
							return new AdvancedVideoElement(null, httpStreamingNetLoader);
						}
					)
				);
				
				multicastLoader = new MulticastNetLoader();
				addItem
				( new MediaFactoryItem
					( "org.osmf.elements.video.rtmfp.multicast"
						, multicastLoader.canHandleResource
						, function():MediaElement
						{
							return new AdvancedVideoElement(null, multicastLoader);
						}
					)
				);
			}
			
			rtmpStreamingNetLoader = new RTMPDynamicStreamingNetLoader();
			addItem
			( new MediaFactoryItem
				( "org.osmf.elements.video.rtmpdynamicStreaming"
					, rtmpStreamingNetLoader.canHandleResource
					, function():MediaElement
					{
						return new AdvancedVideoElement(null, rtmpStreamingNetLoader);
					}
				)
			);
			
			netLoader = new NetLoader();
			addItem
			( new MediaFactoryItem
				( "org.osmf.elements.video"
					, netLoader.canHandleResource
					, function():MediaElement
					{
						return new AdvancedVideoElement(null, netLoader);
					}
				)
			);		
			
			soundLoader = new SoundLoader();
			addItem
			( new MediaFactoryItem
				( "org.osmf.elements.audio"
					, soundLoader.canHandleResource
					, function():MediaElement
					{
						return new AudioElement(null, soundLoader);
					}
				)
			);
			
			addItem
			( new MediaFactoryItem
				( "org.osmf.elements.audio.streaming"
					, netLoader.canHandleResource
					, function():MediaElement
					{
						return new AudioElement(null, netLoader);
					}
				)
			);
			
			imageLoader = new ImageLoader();
			addItem
			( new MediaFactoryItem
				( "org.osmf.elements.image"
					, imageLoader.canHandleResource
					, function():MediaElement
					{
						return new ImageElement(null, imageLoader);
					}
				)
			);
			
			swfLoader = new SWFLoader();
			addItem
			( new MediaFactoryItem
				( "org.osmf.elements.swf"
					, swfLoader.canHandleResource
					, function():MediaElement
					{
						return new SWFElement(null, swfLoader);
					}
				)
			);
		}
		
		private var rtmpStreamingNetLoader:RTMPDynamicStreamingNetLoader;
		private var f4mLoader:F4MLoader;
		private var dvrCastLoader:DVRCastNetLoader;
		private var netLoader:NetLoader;
		private var imageLoader:ImageLoader;
		private var swfLoader:SWFLoader;
		private var soundLoader:SoundLoader;
		
		CONFIG::FLASH_10_1
		{
			private var httpStreamingNetLoader:HTTPStreamingNetLoader;
			private var multicastLoader:MulticastNetLoader;
		}
	}
}

就可以看效果了。创建一个as程序,然后跑跑试试。


package
{
	import flash.display.Sprite;
	import flash.events.Event;
	
	import org.osmf.containers.MediaContainer;
	import org.osmf.events.MediaElementEvent;
	import org.osmf.media.AdvancedMediaFactory;
	import org.osmf.media.MediaElement;
	import org.osmf.media.MediaPlayer;
	import org.osmf.media.URLResource;
	import org.osmf.traits.KeyFramesTraits;


	[SWF(frameRate="25", backgroundColor="#000000", width="800", height="600")]
	public class TestDemo extends Sprite
	{
		
		private var media:MediaElement;
		
		private var player:MediaPlayer;
		
		private var mediaContainer:MediaContainer;
		
		private var factory:AdvancedMediaFactory;
		
		private var keyFrames:Object;
		
		private var keyFramesTraits:KeyFramesTraits;
		
		public function TestDemo()
		{
			addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(event:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			mediaContainer = new MediaContainer();
			mediaContainer.layoutMetadata.percentWidth = 100;
			mediaContainer.layoutMetadata.percentHeight = 100;
			
			factory = new AdvancedMediaFactory();
			addChild(mediaContainer);
			
			media = factory.createMediaElement(new URLResource("http://192.168.1.103/Attachments/UserFiles/00000000000000000000000000000000/MyResourseFiles/20121109/758614a5b17742c79ccc2a1460a46850.flv"));
			media.addEventListener(MediaElementEvent.TRAIT_ADD, traitAdd);
			mediaContainer.addMediaElement(media);
			player = new MediaPlayer(media);
			player.autoPlay = true;
			
		}
		
		private function traitAdd(event:MediaElementEvent):void
		{
			if(event.traitType == KeyFramesTraits.KEY_FRAMES)
			{
				getKeyFrames();
			}
		}
		
		private function getKeyFrames():void
		{
			keyFramesTraits = media.getTrait(KeyFramesTraits.KEY_FRAMES) as KeyFramesTraits;
			
			if(keyFramesTraits)
			{
				var kf:Object = keyFramesTraits.keyFrames;
			}
				
		}
			
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值