| 1 | <?xml version="1.0" encoding="utf-8"?>
|
|---|
| 2 | <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="547" height="348" applicationComplete="init()">
|
|---|
| 3 | <mx:Script>
|
|---|
| 4 | <![CDATA[
|
|---|
| 5 | import vc.kan.nico.CommentField;
|
|---|
| 6 | import mx.controls.Label;
|
|---|
| 7 | import mx.events.CuePointEvent;
|
|---|
| 8 | import flash.filesystem.FileStream;
|
|---|
| 9 | import mx.events.VideoEvent;
|
|---|
| 10 | import vc.kan.net.NicoVideo;
|
|---|
| 11 | import vc.kan.data.DBObject;
|
|---|
| 12 | import flash.filesystem.File;
|
|---|
| 13 | import flash.filesystem.FileMode;
|
|---|
| 14 | import flash.filesystem.FileStream;
|
|---|
| 15 |
|
|---|
| 16 | private var videoDB:DBObject = new DBObject(VideoData);
|
|---|
| 17 | private var seeking:Boolean = false;
|
|---|
| 18 |
|
|---|
| 19 | [Embed(source='assets/play.png')]
|
|---|
| 20 | [Bindable]
|
|---|
| 21 | private var playIcon:Class;
|
|---|
| 22 |
|
|---|
| 23 | [Embed(source='assets/pause.png')]
|
|---|
| 24 | [Bindable]
|
|---|
| 25 | private var pauseIcon:Class;
|
|---|
| 26 |
|
|---|
| 27 | private function init():void {
|
|---|
| 28 | var data:Array = new Array();
|
|---|
| 29 | videoDB.find(function (videos:Array):void {
|
|---|
| 30 | videos.forEach(function(video:Object, idx:int, ary:Array):void {
|
|---|
| 31 | data.push({label: video.title, data: video.video_id});
|
|---|
| 32 | });
|
|---|
| 33 | list.dataProvider = data;
|
|---|
| 34 | });
|
|---|
| 35 | }
|
|---|
| 36 |
|
|---|
| 37 | private function getData():void {
|
|---|
| 38 | var nico:NicoVideo = new NicoVideo(login_user_id.text, login_user_pass.text);
|
|---|
| 39 | nico.download(nico_id.text, function():void {
|
|---|
| 40 | init();
|
|---|
| 41 | });
|
|---|
| 42 | }
|
|---|
| 43 |
|
|---|
| 44 | private function selectList(evt:Event):void {
|
|---|
| 45 | var video_id:String = list.selectedItem.data;
|
|---|
| 46 | var video_file:File = File.applicationStorageDirectory.resolve(video_id + ".flv");
|
|---|
| 47 | video.source = video_file.nativePath;
|
|---|
| 48 |
|
|---|
| 49 | var xml_file:File = File.applicationStorageDirectory.resolve(video_id + ".xml");
|
|---|
| 50 | var fsr:FileStream = new FileStream();
|
|---|
| 51 | fsr.open(xml_file, FileMode.READ);
|
|---|
| 52 | var packet:XML = new XML(fsr.readMultiByte(xml_file.size, "utf-8"));
|
|---|
| 53 | fsr.close();
|
|---|
| 54 |
|
|---|
| 55 | var cue:Array = new Array();
|
|---|
| 56 | for each (var chat:XML in packet.chat) {
|
|---|
| 57 | trace(chat.toString() + "," + chat.@vpos);
|
|---|
| 58 | cue.push({ name: chat.toString()+" ", time: int(chat.@vpos)/100 });
|
|---|
| 59 | }
|
|---|
| 60 | video.cuePointManager.removeAllCuePoints();
|
|---|
| 61 | video.cuePointManager.setCuePoints(cue);
|
|---|
| 62 | video.play();
|
|---|
| 63 | }
|
|---|
| 64 |
|
|---|
| 65 | private function headUpdate(evt:VideoEvent):void {
|
|---|
| 66 | if (this.seeking) {
|
|---|
| 67 | return;
|
|---|
| 68 | }
|
|---|
| 69 | seekBar.maximum = video.totalTime;
|
|---|
| 70 | seekBar.value = evt.playheadTime;
|
|---|
| 71 |
|
|---|
| 72 | this.status = getTimeString(evt.playheadTime) + "/" + getTimeString(video.totalTime);
|
|---|
| 73 | }
|
|---|
| 74 |
|
|---|
| 75 | private function getTimeString(second:Number):String {
|
|---|
| 76 | var hour:int = 0;
|
|---|
| 77 | var min:int = second / 60;
|
|---|
| 78 | var sec:int = second % 60;
|
|---|
| 79 |
|
|---|
| 80 | if (min >= 60) {
|
|---|
| 81 | hour = min / 60;
|
|---|
| 82 | min = min % 60;
|
|---|
| 83 | }
|
|---|
| 84 |
|
|---|
| 85 | return pad0(hour) + ":" + pad0(min) + ":" + pad0(sec);
|
|---|
| 86 | }
|
|---|
| 87 |
|
|---|
| 88 | private function pad0(num:int):String {
|
|---|
| 89 | if (num < 10) {
|
|---|
| 90 | return "0" + String(num);
|
|---|
| 91 | } else {
|
|---|
| 92 | return String(num);
|
|---|
| 93 | }
|
|---|
| 94 | }
|
|---|
| 95 |
|
|---|
| 96 | private function seekStart(evt:Event):void {
|
|---|
| 97 | this.seeking = true;
|
|---|
| 98 | }
|
|---|
| 99 |
|
|---|
| 100 | private function seek(evt:Event):void {
|
|---|
| 101 | video.playheadTime = seekBar.value;
|
|---|
| 102 | this.seeking = false;
|
|---|
| 103 | }
|
|---|
| 104 |
|
|---|
| 105 | private function togglePlay():void {
|
|---|
| 106 | if (video.playing) {
|
|---|
| 107 | video.pause();
|
|---|
| 108 | } else {
|
|---|
| 109 | video.play();
|
|---|
| 110 | }
|
|---|
| 111 | }
|
|---|
| 112 |
|
|---|
| 113 | private function stateChange(evt:VideoEvent):void {
|
|---|
| 114 | if (evt.state == VideoEvent.PLAYING) {
|
|---|
| 115 | playerBtn.source = this.pauseIcon;
|
|---|
| 116 | } else {
|
|---|
| 117 | playerBtn.source = this.playIcon;
|
|---|
| 118 | }
|
|---|
| 119 | }
|
|---|
| 120 |
|
|---|
| 121 | private function volumeChange():void {
|
|---|
| 122 | video.volume = volumeBar.value;
|
|---|
| 123 | }
|
|---|
| 124 |
|
|---|
| 125 | private function cuePoint(event:CuePointEvent):void {
|
|---|
| 126 | var comment:CommentField = new CommentField();
|
|---|
| 127 | comment.start(video, event.cuePointName);
|
|---|
| 128 | }
|
|---|
| 129 | ]]>
|
|---|
| 130 | </mx:Script>
|
|---|
| 131 | <mx:HDividedBox x="0" y="0" width="100%" height="100%">
|
|---|
| 132 | <mx:VBox width="70%" height="100%">
|
|---|
| 133 | <mx:VideoDisplay x="0" y="0" width="100%" height="100%" id="video"
|
|---|
| 134 | cuePointManagerClass="mx.controls.videoClasses.CuePointManager"
|
|---|
| 135 | playheadUpdate="headUpdate(event)"
|
|---|
| 136 | stateChange="stateChange(event)"
|
|---|
| 137 | cuePoint="cuePoint(event)" />
|
|---|
| 138 | <mx:HBox width="100%" height="20">
|
|---|
| 139 | <mx:Image id="playerBtn" source="{playIcon}" x="10" y="10" click="togglePlay()" />
|
|---|
| 140 | <mx:HSlider id="seekBar" width="100%" height="18" minimum="0" snapInterval="1"
|
|---|
| 141 | mouseDown="seekStart(event)"
|
|---|
| 142 | thumbPress="seekStart(event)"
|
|---|
| 143 | thumbRelease="seek(event)"
|
|---|
| 144 | mouseUp="seek(event)" />
|
|---|
| 145 | <mx:Image source="@Embed('assets/volume.png')" />
|
|---|
| 146 | <mx:HSlider id="volumeBar" width="50" height="18" minimum="0" maximum="1" snapInterval="0.01" value="0.75"
|
|---|
| 147 | change="volumeChange()" />
|
|---|
| 148 | </mx:HBox>
|
|---|
| 149 | </mx:VBox>
|
|---|
| 150 | <mx:Canvas width="30%" height="100%">
|
|---|
| 151 | <mx:Label x="0" y="2" text="ID" />
|
|---|
| 152 | <mx:Label x="0" y="28" text="Pass" />
|
|---|
| 153 | <mx:TextInput x="39" y="0" id="login_user_id" width="121"/>
|
|---|
| 154 | <mx:TextInput x="39" y="26" id="login_user_pass" displayAsPassword="true" width="121"/>
|
|---|
| 155 | <mx:Button x="76" y="56" label="get data" click="getData()"/>
|
|---|
| 156 | <mx:TextInput x="0" y="56" width="75" id="nico_id"/>
|
|---|
| 157 | <mx:List x="0" y="86" width="100%" height="260" id="list" click="selectList(event)"></mx:List>
|
|---|
| 158 | </mx:Canvas>
|
|---|
| 159 | </mx:HDividedBox>
|
|---|
| 160 | </mx:WindowedApplication>
|
|---|