AIRアプリで動画ファイルの解像度の取得したかっただけなのだが、ActionScriptでは動画を読み込まないとそれがわからないのです。解像度の取得だけに容量の大きなファイルを読み込むのは現実的ではなかったためffmpegを使用して解像度を取得することにしました。
今回AIRからffmpegコマンドラインを実行させていますが、同様なことをすればUnityやOFなど他の言語からでも取得できます。
環境:Windows10
ffmpegについて
ffmpegは動画のコンバートをするのに便利なソフトでコマンドラインでも使うことができます。ダウンロードはこちらから。
ffmpegで動画の解像度を取得する方法
以下のように本来はコンバートに使うコマンドのですが
1 |
ffmpeg.exe -i [inputMovieFile] [outputMovieFile] |
今回はコンバートしないので以下のように[movieFile]は一つだけにします。
1 |
ffmpeg.exe -i [movieFile] |
実際にコマンドを実行させるとこのようになります。本来の使い方と違うためエラー情報が表示されます。その20行目にファイルサイズが記載されています。
このコマンドをAIRから実行して文字列を加工すれば解像度を取得できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
F:\source\Apps\ffmpeg>ffmpeg.exe -i ../../contents/movie.mp4 ffmpeg version N-82274-g34aeb5d Copyright (c) 2000-2016 the FFmpeg developers built with gcc 5.4.0 (GCC) configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-dxva2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-bzlib --enable-libebur128 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-decklink --enable-zlib libavutil 55. 35.100 / 55. 35.100 libavcodec 57. 66.101 / 57. 66.101 libavformat 57. 57.100 / 57. 57.100 libavdevice 57. 2.100 / 57. 2.100 libavfilter 6. 66.100 / 6. 66.100 libswscale 4. 3.100 / 4. 3.100 libswresample 2. 4.100 / 2. 4.100 libpostproc 54. 2.100 / 54. 2.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '../../contents/movie.mp4': Metadata: major_brand : mp42 minor_version : 0 compatible_brands: mp42mp41 creation_time : 2014-04-16T05:26:41.000000Z Duration: 00:00:14.91, start: 0.000000, bitrate: 5915 kb/s Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv), 720x480 [SAR 32:27 DAR 16:9], 5909 kb/s, SAR 853:720 DAR 853:480, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default) Metadata: creation_time : 2014-04-16T05:26:41.000000Z handler_name : Alias Data Handler encoder : AVC Coding At least one output file must be specified |
参考: http://tohka383.hatenablog.jp/entry/20111212/1323648512
AIRからffmpegを実行して解像度を取得する
コマンドラインからffmpegを実行するので nativeProcessStartupInfo.executable を使用し、後は文字列を加工していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
public function GetMovieInfo(filePath:String){ var fileNameArr:Array = fileName.split("."); if(fileNameArr[fileNameArr.length - 1] != "mp4") return; // コマンドプロンプトで実行 var file:File = new File("C:\\Windows\\System32\\cmd.exe"); nativeProcessStartupInfo.executable = file; var processArgs:Vector.<String> = new Vector.<String>(); processArgs.push("/c"); processArgs.push(".\\ffmpeg.exe"); processArgs.push("-i"); processArgs.push(filePath); nativeProcessStartupInfo.arguments = processArgs; var process:NativeProcess = new NativeProcess(); process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, OnOutputData); process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA,OnError(filePath)); process.start(nativeProcessStartupInfo); // こちらは使いませんが一応。 function OnOutputData(e:ProgressEvent){ trace("STANDARD_OUTPUT_DATA"); /*var standardOutput:IDataInput = process.standardOutput; var output:String = standardOutput.readMultiByte(e.bytesLoaded,"utf-8"); trace(output);*/ } // ffmpegからこちらに情報がいきます。 function OnError(filePath:String):Function{ return function (e:ProgressEvent):void{ var response:String = process.standardError.readUTFBytes(process.standardError.bytesAvailable); // (1)文字列を改行で区切りStreamの入っている行のみを抽出します。 if(response == undefined || response == "") return; var responseArr:Array = response.split("\n"); var infoLine:String = ""; for(var i:int = 0; i < responseArr.length;i++){ if(responseArr[i].indexOf("Stream") >= 0 && responseArr[i].indexOf("Video") >= 0){ infoLine = responseArr[i]; } } // (2)文字列をコンマで区切り、解像度情報がある部分を抽出します。 if(infoLine == undefined || infoLine == "") return; var sizeInfo:String = ""; var infoArr:Array = infoLine.split(","); for(i = 0; i < infoArr.length;i++){ if(infoArr[i].indexOf("[SAR") >= 0){ sizeInfo = infoArr[i]; } } // (3)文字列を空白で区切り解像度情報がある部分を抽出します。 if(sizeInfo == undefined || sizeInfo == "") return; var pixelInfo:String = ""; var sizeArr:Array = sizeInfo.split(" "); for(i = 0; i < sizeArr.length;i++){ if(sizeArr[i].indexOf("x") >= 0){ pixelInfo = sizeArr[i]; } } // (4)縦と横を抽出します。 if(pixelInfo == undefined || pixelInfo == "") return; var pixelArr:Array = pixelInfo.split("x"); trace("filename: " + filePath); trace("解像度: " + pixelArr[0] + "x" + pixelArr[1]); } } } |
コメントを残す