Flexのインターフェイスを提供しました。
Flexのインターフェイスを提供しました。
こんな感じです。
http://tooble.u-aizu.ac.jp/aizoom/
サイトの特徴は
- 動画検索
- セリフからシーンを検索
- 音声からシーンを検索(現在未対応)
っとなってます。
音声保存はred5を使用してます。
ただ、ポートの問題なのか現在は機能していません。
とりあえずのα版公開です(^−^)
ソースはこちら
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:reflector="com.rictus.reflector.*" horizontalScrollPolicy="off" verticalScrollPolicy="off" layout="absolute" creationComplete="init()" backgroundGradientAlphas="[1.0, 1.0]" backgroundGradientColors="[#FFFFFF, #999999]"> <mx:Style> TileList{ borderStyle: solid; borderThickness:0; } </mx:Style> <mx:Script> <![CDATA[ import mx.rpc.events.ResultEvent; import mx.core.UIComponent; import mx.effects.easing.*; //初期化関数 private function init():void{ setNetConnection(); myPause.play(); // playSound("Crackers2.mp3"); //3Dシーンの作成 makeScene(); } //youtube読み込み private function onSearch():void{ pBar.visible = true; youtubeSearch.send({ "tag":word.text, "page":1 }); searchEffect.play(); viewCanvas.visible = true; } //youtube読み込み完了 private function onFinish():void{ pBar.visible = false; // titleList.visible = true; myLog.text += "" + youtubeSearch.lastResult; PV3DMouseInteractive() } //アイテムクリック private var flv_id:String; private function onItemClick():void{ pBar.visible = true; var index:int = titleList.selectedIndex; flv_id = youtubeSearch.lastResult.items.item[index].flv_id; flvurlSearch.send({ "flv_id":flv_id }); } //flvURLの取得完了 private function onFinish2():void{ myCanvasFlv.visible = true; myFlv.source = flvurlSearch.lastResult.flvurl; pBar.visible = false; } //flv再生ストップ private function onHide():void{ myFlv.stop(); } //セリフ検索のメニュー表示 private function showMenu():void{ if( myCanvasFlv.mouseY < 80 ){ //メニュー表示 myCanvasWord.visible = true; }else if( myCanvasFlv.mouseX > 80 && !myHideWord.isPlaying){ myCanvasWord.visible = false; } if( myCanvasFlv.mouseY > this.height - flvList.height - 30 ){ //メニュー表示 flvList.visible = true; }else if( myCanvasFlv.mouseX > 80 && !myHideWord2.isPlaying){ flvList.visible = false; } } //flvをクリックで再生停止 private function onFlvClick():void{ myCanvasFlv.visible = false; myFlv.close(); } //faultイベント private function onFault():void{ myLog.text = "on Fault"; } // セリフ検索 private function onWordSearch():void{ pBar.visible = true; wordSearch.send({ "flv_id":flv_id, "word":wordSerihu.text }); } // セリフ位置から動画を再生 private function onWordSelect():void{ var tmp2:Array = String( wordList.selectedItem.starttime ).split( ":" ); myLog.text += String( int( tmp2[0] ) * 60 + int( tmp2[1] ) ); myFlv.stop(); myFlv.source = webroot + "cache/flv/" + flv_id + ".flv"; myFlv.playheadTime = int( tmp2[0] ) * 60 + int( tmp2[1] ); myFlv.play(); } //効果音再生用関数 private function playSound(file:String):void{ var soundURL:URLRequest; var mySound:Sound; var mySoundChannel:SoundChannel; var mySoundTransform:SoundTransform; soundURL = new URLRequest(file); mySound = new Sound(soundURL); mySoundChannel = mySound.play(); mySoundTransform = new SoundTransform(); mySoundTransform.volume = 0.6; mySoundChannel.soundTransform = mySoundTransform; } //マイクから録音 import com.renaun.samples.net.FMSConnection; private var nc:FMSConnection; private var clientID:Number; private var ns:NetStream; private var lastVideoName:String; private function showRec():void{ btnStart.enabled = true; btnStop.enabled = false; } private function setNetConnection():void{ // Netコネクションの設定 NetConnection.defaultObjectEncoding = flash.net.ObjectEncoding.AMF0; nc = new FMSConnection(); nc.addEventListener( "success", connectionSuccessHandler ); nc.connect( "rtmp://163.143.132.106/oflaDemo" ); } private function connectionSuccessHandler( event:Event ):void { clientID = nc.clientID; } private function startClick():void{ btnStart.enabled = false; btnStop.enabled = true; // ネットストリーム作成 ns = new NetStream(nc); //メタデータの設定(なんかないと怒られる) var client:Object = new Object(); client.onMetaData = onMetaData; ns.client = client // マイクの設定 var mic:Microphone = Microphone.getMicrophone(); ns.attachAudio(mic); //ファイル名 lastVideoName = "voice_" + int( Math.random() * 100000000 ); //録音スタート ns.publish(lastVideoName, "record"); } private function stopClick():void{ //録音停止 ns.close(); //録音したものを再生(なんかめんどっちい var uiC:UIComponent = new UIComponent(); var video:Video = new Video(320,240); video.attachNetStream( ns ); uiC.addChild(video); videoContainer.addChild(uiC); // ns.play(lastVideoName + ".flv"); //phpにflv => wave => 複素変換リクエスト http.send({ "voiceid":lastVideoName, "flv_id":flv_id }); pBar.visible = true; //読み込み完了時 http.addEventListener(ResultEvent.RESULT , function():void{ pBar.visible = false; wordList.dataProvider = http.lastResult.frames.frame; btnStart.enabled = true; btnStop.enabled = false; }); } // メタデータ取得 private function onMetaData(data:Object):void{ } //ペーパービジョン3D import caurina.transitions.Tweener; import flash.display.*; import flash.events.*; import flash.net.URLLoader; import flash.net.URLRequest; import org.papervision3d.cameras.*; import org.papervision3d.core.proto.MaterialObject3D; import org.papervision3d.events.InteractiveScene3DEvent; import org.papervision3d.materials.*; import org.papervision3d.objects.primitives.*; import org.papervision3d.render.*; import org.papervision3d.scenes.*; import org.papervision3d.view.*; public var viewport :Viewport3D; public var scene :Scene3D; public var camera :FreeCamera3D; public var renderer :BasicRenderEngine; public var R:int = 500; public var num:int = 20; public var planeArr:Object = []; public var urlXMLURL:URLRequest; public var myXML:XML; public var myLoader:URLLoader; private var material:MaterialObject3D; private function makeScene():void{ myImage.setFocus(); myImage.tabEnabled = true; //3Dの初期設定 viewport = new Viewport3D(0, 0, true, true); myImage.addChild( viewport ); //レンダラーの設定 renderer = new BasicRenderEngine(); //シーン作成 scene = new Scene3D(); // カメラの作成 camera = new FreeCamera3D(); camera.zoom = 5; //毎フレーム呼び出されるイベントを追加 this.addEventListener( Event.ENTER_FRAME, this.loop_Proc ); } //初期化 public function PV3DMouseInteractive():void{ //再検索用にクリア removePlane(); makePlane(); } private function clearPlane():void{ for(var i:int = 0 ; i < num ; i++){ Tweener.addTween(planeArr[i], { x:0, y:0, time:1, transition:"easeout", onComplete:function():void{ scene.removeChild( planeArr[i] ); } }); var p:Plane = new Plane(); } } private function removePlane():void{ for(var i:int = 0 ; i < planeArr.length ; i++){ scene.removeChild( planeArr[i] ); } } //平面の作成 public function makePlane():void { for(var i:int = 0 ; i < num ; i++){ material = new BitmapFileMaterial(youtubeSearch.lastResult.items.item[i].thumbnail_url); material.interactive = true; material.doubleSided = true; planeArr[i] = new Plane(material,130,97); //平面シーンに追加 scene.addChild(planeArr[i]); planeArr[i].name = i; //マウスでいろいろできるように planeArr[i].addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, onClickHandler); planeArr[i].addEventListener(InteractiveScene3DEvent.OBJECT_OVER, onMouseOverHandler); planeArr[i].addEventListener(InteractiveScene3DEvent.OBJECT_OUT, onMouseOutHandler); } ScalePlane(); } /**---------------------------------------------------------------------- * loop_Proc * 毎フレーム呼び出される 関数 -----------------------------------------------------------------------*/ public function loop_Proc(event:Event):void{ this.renderer.renderScene(scene, camera, viewport); } //平面状に配置 private function ScalePlane():void{ Tweener.addTween( camera ,{ x:0, y:0, z:-600, time:2, transition:"easeout" }); for(var i:int = 0 ; i < num ; i++){ Tweener.addTween(planeArr[i], { x:int(i/5)*200 - 460, y:(i%5)*150 - 250, time:1, transition:"easeout" }); } } //円状に配置 private function initCircle():void{ Tweener.addTween( camera ,{ x:0, y:0, z:-1000, time:2, transition:"easeout" }); for(var i:int = 0 ; i < num ; i++){ Tweener.addTween(planeArr[i], { x:R * Math.cos(2*(i/num)*Math.PI) - 100, y:R * Math.sin(2*(i/num)*Math.PI) + 50, time:1, transition:"easeout" }); } } //ライン状 private function initPlane():void{ Tweener.addTween( camera ,{ x:0, y:0, z:-800, time:2, transition:"easeout" }); for(var i:int = 0 ; i < num ; i++){ Tweener.addTween(planeArr[i], { x:i*140 - 1000, y:0, time:1, transition:"easeout" }); } } //サムネイルマウスクリック private function onClickHandler(evt:Event):void{ Tweener.addTween(camera, { x:evt.target.x, y:evt.target.y, z:evt.target.z - 500, time:1, transition:"easeout" }); flv_id = youtubeSearch.lastResult.items.item[evt.target.name].flv_id; //FLVのURLをゲット flvurlSearch.send({ "flv_id":flv_id }); pBar.visible = true; } //サムネイルマウスオーバー private function onMouseOverHandler(evt:Event):void { Tweener.addTween(evt.target, { scaleX:2, scaleY:2, time:0.5, z:- 10, transition:"easeout" }); } //サムネイルマウスアウト private function onMouseOutHandler(evt:Event):void { Tweener.addTween(evt.target, { scaleX:1, scaleY:1, z:0, time:0.5, transition:"easeout" }); } ]]> </mx:Script> <mx:Style> Button { cornerRadius: 4; highlightAlphas: 0.54, 0.58; fillAlphas: 0.6, 0.7, 0.75, 0.65; fillColors: #ffffff, #666666, #ffffff, #eeeeee; } </mx:Style> <!-- ################### 設定 ###################--> <mx:String id="webroot">http://163.143.132.106/aizoom/</mx:String> <!-- ################### フィルター ###################--> <mx:DropShadowFilter blurX="10" blurY="10" distance="0" color="0xff0000" alpha="0.8" id="myDrop"/> <!-- ################### HTTPサービス ###################--> <mx:HTTPService id="youtubeSearch" url="{webroot+'index.php?flv_id=&type=xml&word='}" useProxy="false" method="GET" resultFormat="e4x" result="onFinish()" fault="onFault()" /> <mx:HTTPService id="flvurlSearch" url="{webroot+'index.php?type=flvurl&flv_id='}" useProxy="false" method="GET" resultFormat="e4x" result="onFinish2()" fault="onFault()"/> <mx:HTTPService id="wordSearch" url="{webroot+'index.php?movie_site=youtube&page=1&type=xml&tag='}" useProxy="false" method="GET" resultFormat="e4x" result="{pBar.visible = false;}"/> <mx:HTTPService id="http" url="{webroot+'index.php?type=voice'}" useProxy="false" resultFormat="e4x" fault="onFault()" result="{pBar.visible=false;}"/> <!-- ################### エフェクト ###################--> <mx:Pause id="myPause" duration="2800" effectEnd="{formInput.visible = true;}" /> <mx:Move id="showForm" yFrom="200" yTo="300" easingFunction="Back.easeOut"/> <mx:Sequence id="searchEffect"> <mx:Glow blurXFrom="10" blurXTo="0" blurYFrom="10" blurYTo="0" color="0xff0000" alphaFrom="1" alphaTo="0" /> <mx:Parallel> <mx:Move xTo="10" yTo="10" target="{mySwf}" easingFunction="Back.easeInOut"/> <mx:Move xTo="70" yTo="0" target="{formInput}" easingFunction="Back.easeInOut"/> <mx:Zoom zoomHeightTo="0.3" zoomWidthTo="0.3" target="{mySwf}" easingFunction="Back.easeInOut"/> </mx:Parallel> </mx:Sequence> <mx:Sequence id="ListShow" target="{titleList}"> <mx:WipeDown duration="800"/> <mx:Glow blurXFrom="10" blurXTo="0" blurYFrom="10" blurYTo="0" target="{titleList}"/> </mx:Sequence> <mx:Sequence id="myFlvShow"> <mx:Parallel> <mx:Zoom zoomHeightFrom="0.8" zoomHeightTo="1" zoomWidthFrom="0.8" zoomWidthTo="1" easingFunction="Back.easeInOut"/> <mx:Fade alphaFrom="0.5" alphaTo="1"/> </mx:Parallel> </mx:Sequence> <mx:Parallel id="myFlvHide"> <mx:Fade alphaFrom="1" alphaTo="0.5"/> <mx:Zoom zoomHeightFrom="1.0" zoomHeightTo="0.8" zoomWidthFrom="1.0" zoomWidthTo="0.8" easingFunction="Back.easeIn"/> </mx:Parallel> <mx:Move yFrom="-200" yTo="0" id="myShowWord" duration="200"/> <mx:Move yFrom="0" yTo="-200" id="myHideWord" duration="200"/> <mx:Move yTo="{myCanvasFlv.height-flvList.height}" id="myShowWord2" duration="200"/> <mx:Move yTo="{myCanvasFlv.height+flvList.height}" id="myHideWord2" duration="200"/> <mx:Sequence id="viewCanvasShow"> <mx:Move xFrom="-100" xTo="{viewCanvas.x}"/> </mx:Sequence> <!-- ################### コンポーネント ###################--> <!--TOP--> <mx:SWFLoader source="@Embed('Movie1.swf')" id="mySwf" x="{this.width/2-100}"/> <mx:Canvas y="220" width="288" height="124" id="formInput" visible="false" showEffect="showForm" x="{this.width/2-120}"> <mx:TextInput x="21" y="47" text="ニュース" id="word" fontSize="20" backgroundAlpha="0.9" cornerRadius="5" borderColor="0x999999" borderStyle="solid" borderThickness="1" dropShadowColor="0x000000" dropShadowEnabled="true" shadowDistance="0" enter="onSearch()"/> <mx:Button x="189" y="47" label="動画検索" click="onSearch()" width="78" height="35"/> </mx:Canvas> <mx:TileList x="22" y="114" width="720" height="600" id="titleList" columnWidth="140" rowHeight="140" columnCount="4" itemClick="onItemClick()" dataProvider="{youtubeSearch.lastResult.items.item}" backgroundAlpha="0" horizontalScrollPolicy="off" verticalScrollPolicy="off" visible="false" showEffect="ListShow"> <mx:itemRenderer> <mx:Component> <mx:VBox verticalScrollPolicy="off" horizontalScrollPolicy="off"> <mx:Image source="{data.thumbnail_url}" width="120"/> <mx:Text text="{data.title}" width="120"/> </mx:VBox> </mx:Component> </mx:itemRenderer> </mx:TileList> <!--フッター--> <mx:LinkButton label="会津大学画像処理額講座" horizontalCenter="0" color="0xffffff" bottom="10" showEffect="Zoom"/> <!--PV3D--> <mx:Image width="100%" height="100%" id="myImage" /> <!--左コンテンツ--> <mx:Canvas x="4" y="113" width="82" height="131" id="viewCanvas" visible="false" showEffect="viewCanvasShow"> <mx:Button x="10" y="9" label="□" click="ScalePlane()" width="62" height="32"/> <mx:Button x="10" y="49" label="○" click="initCircle()" width="62" height="32"/> <mx:Button x="10" y="89" label="―" click="initPlane()" width="62" height="32" visible="false"/> </mx:Canvas> <!--大画面ビデオ--> <mx:VideoDisplay x="10" y="10" width="10" height="10" id="videoContainer" visible="false"/> <!--メイン大コンテンツ--> <mx:Canvas backgroundAlpha="1" backgroundColor="0xffffff" mouseMove="showMenu()" visible="false" width="100%" height="100%" id="myCanvasFlv" horizontalScrollPolicy="off" verticalScrollPolicy="off" showEffect="myFlvShow" hideEffect="myFlvHide"> <!--ビデオ大画面--> <mx:VideoDisplay x="0" y="0" width="100%" height="100%" id="myFlv" click="onFlvClick()" backgroundColor="0x000000" /> <!--セリフ検索--> <mx:Canvas x="0" y="-100" width="100%" height="80" backgroundColor="#FFFFFF" backgroundAlpha="0.3" id="myCanvasWord" horizontalScrollPolicy="off" verticalScrollPolicy="off" dropShadowColor="0x000000" dropShadowEnabled="true" borderColor="0xcccccc" borderStyle="solid" borderThickness="2" visible="true" showEffect="myShowWord" hideEffect="myHideWord"> <mx:TabNavigator x="3" y="4" width="232" height="70"> <!--テキストで入力--> <mx:Canvas label="セリフ検索" width="100%" height="100%"> <mx:TextInput x="9" y="7" width="120" text="本日の" id="wordSerihu"/> <mx:Button x="137" y="7" label="セリフ検索" click="onWordSearch()" width="82"/> </mx:Canvas> <!--マイクで入力--> <mx:Canvas label="マイク検索" width="100%" height="100%"> <mx:Button x="33" y="7" label="● スタート" id="btnStart" click="startClick()" enabled="true" color="0xff0000"/> <mx:Button x="131" y="7" label="|| ストップ" id="btnStop" click="stopClick()" enabled="false" color="0xff0000"/> </mx:Canvas> </mx:TabNavigator> <!--候補サムネイルリスト--> <mx:TileList width="840" x="239" y="4" showScrollTips="false" id="wordList" borderColor="0xcccccc" borderStyle="solid" borderThickness="1" itemClick="onWordSelect()" backgroundAlpha="0.3" height="70" columnWidth="100" rowCount="1" dataProvider="{wordSearch.lastResult.frames.frame}"> <mx:itemRenderer> <mx:Component> <mx:Canvas verticalScrollPolicy="off" horizontalScrollPolicy="off"> <mx:TextArea width="80" height="15" text="{data.starttime}" color="0x333333" backgroundColor="0xcccccc"/> <mx:Image source="{data.thumimage}" width="80" height="80" y="20" completeEffect="Fade"/> </mx:Canvas> </mx:Component> </mx:itemRenderer> </mx:TileList> </mx:Canvas> <!--youtubeリスト--> <mx:TileList width="100%" y="{myCanvasFlv.height}" showScrollTips="false" id="flvList" alpha="0.8" borderColor="0xcccccc" borderStyle="solid" borderThickness="1" dropShadowColor="0x000000" dropShadowEnabled="true" shadowDirection="bottom" shadowDistance="-3" itemClick="{titleList.selectedIndex = flvList.selectedIndex; onItemClick()}" backgroundAlpha="0" height="80" columnWidth="100" rowCount="1" dataProvider="{youtubeSearch.lastResult.items.item}" direction="horizontal" visible="true" showEffect="myShowWord2" hideEffect="myHideWord2"> <mx:itemRenderer> <mx:Component> <mx:Canvas verticalScrollPolicy="off" horizontalScrollPolicy="off"> <mx:Image source="{data.thumbnail_url}" width="100" showEffect="Fade" completeEffect="Fade" /> </mx:Canvas> </mx:Component> </mx:itemRenderer> </mx:TileList> </mx:Canvas> <mx:TextArea id="myLog" x="901" y="23" width="178" height="543" backgroundAlpha="0" visible="false"/> <!--ロードバー--> <mx:ProgressBar id="pBar" x="0" y="0" indeterminate="true" themeColor="#4D4D4D" width="100%" trackHeight="10" alpha="0.5" label="" visible="false" showEffect="WipeRight" hideEffect="WipeRight"/> </mx:Application>