NetStreamとVideoを組み合わせたmp4の再生
学会を間近に控え、発表用のデモを作成中です。
そのデモの中でローカルにあるflvやmp4の動画をFlex上のコンポーネントで指定の秒数から再生する必要が出てきました。
単純にFlexのVideoDisplayコンポーネントを使えば再生出来ると思ってたのですが、いざやってみるとローカルのファイルがなぜか再生できない(セキュリティ上??)
で、色々と調べているとNetStreamとVideo(flash.media.Video)を組み合わせることでお手軽にローカルの動画をFlex上で再生できるらしい。
で、色んな所参考にして、
var nc:NetConnection; var ns:NetStream; var player:Video; var uiC:UIComponent = new UIComponent(); nc = new NetConnection(); nc.connect(null); ns = new NetStream(nc); player = new Video(512, 384); player.attachNetStream(ns); uiC.addChild(player); canvas.addChild(uiC); ns.play("動画ファイルパス"); ns.seek(120);
と書いてみたのですが、flvは再生出来るものの、mp4はonMetaDataがどうのと怒られる。
で、また色々なところを参考にした結果、NetStreamのclientプロパティを使うと上手くいくらしい。で、
var nc:NetConnection; var ns:NetStream; var player:Video; var uiC:UIComponent = new UIComponent(); var cObj:Object = new Object(); cObj.onMetaData = function():void{ _seek(); }; nc = new NetConnection(); nc.connect(null); ns = new NetStream(nc); ns.client = cObj; player = new Video(512, 384); player.attachNetStream(ns); uiC.addChild(player); canvas.addChild(uiC); ns.play("動画ファイルパス"); function _seek():void{ ns.seek(120); }
としたら、怒られることなく映りました。
が、シークをしてくれません。
正確には、シークはしてくれるのですがシーク後になぜか再生がストップしてしまうのです。
resumeメソッドも試してみましたが解消しません。
もっと正確に言うと、数回に一回はきちんと再生してくれます。
これでは使い物にならないので、また色々と探したのですが、僕の検索能力では有用な情報が見つからない。
で、悩んで色々と試した結果、上のソースで再生と同時にシークをせず、再生中にボタンを押してシークをすることは可能だったので、再生とシークの処理時間に差がないと上手く行かないのではという結論にいたり、タイマー使って
var nc:NetConnection; var ns:NetStream; var player:Video; var uiC:UIComponent = new UIComponent(); var cObj:Object = new Object(); cObj.onMetaData = function():void{ var timer:Timer = new Timer(100,1); timer.addEventListener(TimerEvent.TIMER, _seek); timer.start(); }; nc = new NetConnection(); nc.connect(null); ns = new NetStream(nc); ns.client = cObj; player = new Video(512, 384); player.attachNetStream(ns); uiC.addChild(player); canvas.addChild(uiC); ns.play("動画ファイルパス"); function _seek(e:TimerEvent):void{ ns.seek(120); }
としてやると無事上手くいきました。
(正確には、一瞬、動画の頭の部分の映像と音声が入る。まあ、無視できるレベル)
flvではこんな面倒なことをしなくても良かったのですが、なぜかmp4は再生中でないとシークがうまく出来ないようです。
(ニコ動で動画ページのURLの最後に?from=120などと入れるとその秒数から再生してくれるのですが、これもなぜかmp4の動画に対しては正しい挙動をしません。もしかすると同じようなことが原因か…)
もちろん、明らかにこれは完全な解決方法ではないでしょうし、もっと他にスマートな方法はあるのかもしれないですので、指摘ある方お願いしますmm
ちなみに、半日この問題の解決で時間を使いました…
※参考にしたいろんな所のいくつか
http://dev.convexstyle.net/2007/12/videodisplay_netstreamseek.html
http://dev.convexstyle.net/2008/04/h264_progressive.html
http://blog.gu-raphix.com/2009/02/as3-mp4flv.html