Java で ffmpeg を呼び出してビデオ形式を flv に変換する方法の詳細な説明 注:以下のプログラムは Linux で実行されます。Windows で rmvb を avi に変換すると問題が発生します。成功するには、drv43260.dll をダウンロードして C:WindowsSystem32 に置く必要があります。 最近、ビデオ管理システムを作成しているのですが、異なる形式を flv 形式に変換する方法という大きな問題に遭遇しました。インターネットでいろいろ検索した後、自分で要約、分類、整理して、ようやく理解できました!動画変換、動画スクリーンショット、オリジナルファイルの削除の機能を同時に実現します! フォーマット変換の主な原則は、まず Java を使用して ffmpeg exe ファイルを呼び出すことです。 ただし、rmvb など、一部の形式は ffmpeg で処理できません。この場合、最初に mencoder を呼び出して形式を avi に変換し、次に flv に変換することができます。 私は主に3つのクラスを書いています: Conver.java ConverBegin.java ConverVideo.java Conver.java のコードは次のとおりです。 パッケージ org.Conver; java.awt.BorderLayout をインポートします。 javax.swing.JFrame をインポートします。 javax.swing.JScrollPane をインポートします。 javax.swing.JTextArea をインポートします。 @SuppressWarnings("シリアル") パブリッククラスConverはJFrameを拡張します{ パブリック静的 JTextArea OutShowLog; パブリック変換() { setTitle("FLV変換"); サイズを500、400に設定します。 デフォルトの閉じる操作を設定します(JFrame.EXIT_ON_CLOSE); OutShowLog = 新しい JTextArea(); JScrollPane OutPane = newJScrollPane(OutShowLog); OutPane に BorderLayout.CENTER を追加します。 表示をtrueに設定します。 } パブリック静的void main(String args[]) { 新しいConver(); 変換開始 cb = 新しい変換開始(); cb.start(); } } ConverBegin.java コードは次のとおりです。 パッケージ org.Conver; java.io.File をインポートします。 パブリッククラスConverBeginはThreadを拡張します{ 文字列[] ff; パブリックボイドrun(){ (真)の間{ 文字列フォルダパス = "other/"; //文字列パス = null; ファイル f = newFile(フォルダーパス); (f.isDirectory())の場合{ ff = f.list(); 整数 i = 0; (i< ff.length) の間 { 新しいConverVideo(フォルダパス+ff[i]).beginConver(); 私は++; } Conver.OutShowLog.append("---------------変換された合計 "+ff.length+"------------videos-------------"); ff = null; } f = ヌル; 試す { スレッドをスリープ状態にします(10000); } キャッチ (InterruptedException) { // 失敗した場合は、スレッドを再起動します this.start(); } } } } ConverBegin.javaコードは以下のとおりです パッケージ org.Conver; java.io.File をインポートします。 java.io.IOException をインポートします。 java.io.InputStream をインポートします。 java.util.Date をインポートします。 java.util.List をインポートします。 パブリッククラスConverVideo { プライベート日付dt; プライベートな長い開始時間; プライベート文字列 PATH; private String filerealname; // ファイル名に拡張子が含まれませんprivate Stringfilename; // 拡張子が含まれますprivate String videofolder = "other/"; //その他のビデオ形式のディレクトリprivate String flvfolder ="flv/"; //flv ビデオ ディレクトリprivateStringffmpegpath="ffmpeg/ffmpeg.exe"; //ffmpeg.exe ディレクトリprivateStringmencoderpath="ffmpeg/mencoder"; //mencoder ディレクトリprivateStringvideoRealPath="flv/"; //スクリーンショット ビデオ ディレクトリ; privateString imageRealPath = "img/"; //スクリーンショットの保存ディレクトリ //privateString batrealpath = "ffmpeg/ffmpeg.bat"; //batディレクトリ publicConverVideo(){} パブリックConverVideo(文字列パス) { PATH = パス; } パブリック文字列 getPATH() { PATH を返します。 } パブリック void setPATH(文字列パス) { PATH = パス; } パブリックブールbeginConver(){ ファイル fi = new File(PATH); ファイル名 = fi.getName(); ファイルの実名 = ファイル名.substring(0,ファイル名.lastIndexOf(".")) .toLowerCase(); Conver.OutShowLog.append("----受信したファイル ("+PATH+") を変換する必要があります--------------------------"); if (!checkfile(PATH)) { Conver.OutShowLog.append(PATH+ "ファイルが存在しません"+" "); false を返します。 } dt = 新しい日付(); 開始時刻 = dt.getTime(); Conver.OutShowLog.append("----ファイルの変換を開始します ("+PATH+")--------------------------"); (プロセス())の場合{ 日付 dt2 = 新しい日付(); Conver.OutShowLog.append("変換が成功しました"); 長い終了時間 =dt2.getTime(); long timecha = (終了時間 - 開始時間); 文字列 totaltime =sumTime(timecha); Conver.OutShowLog.append("共有: " + totaltime+" "); if(プロセスイメージ()) { Conver.OutShowLog.append("スクリーンショットが成功しました"); }それ以外 { Conver.OutShowLog.append("スクリーンショットに失敗しました"); } PATH = null; true を返します。 }それ以外 { PATH = null; false を返します。 } } パブリックブール値processImg() { // System.out.println(新しいファイル名 + "->" +newimg); リスト<String, String> = 新しい java.util.ArrayList(); ffmpegpathを追加します。 commend.add("-i"); commend.add(videoRealPath+filerealname+".flv"); commend.add("-y"); commend.add("-f"); command.add("image2"); commend.add("-ss"); commend.add("38"); commend.add("-t"); commend.add("0.001"); commend.add("-s"); commend.add("320x240"); commend.add(imageRealPath+filerealname+".jpg"); 試す { ProcessBuilder ビルダー = 新しい ProcessBuilder(); ビルダー.command(commend); ビルダーを起動します。 true を返します。 } キャッチ (例外 e) { e.printStackTrace(); false を返します。 } } プライベートブールプロセス() { int 型 = checkContentType(); ブール値ステータス = false; (タイプ == 0)の場合{ // status =processFLV(PATH); // ファイルを直接 flv ファイルに変換します status =processFLV(PATH); } そうでない場合 (type == 1) { 文字列 avifilepath =processAVI(type); (avifilepath == null)の場合 falseを返します。 //aviファイルが取得されていないelse { System.out.println("kaishizhuang"); status =processFLV(avifilepath); // aviをflvに変換する } } ステータスを返します。 } プライベートint checkContentType() { 文字列型 =PATH.substring(PATH.lastIndexOf(".") + 1, PATH.length()) .toLowerCase(); //ffmpeg が解析できる形式: (asx、asf、mpg、wmv、3gp、mp4、mov、avi、flv など) (type.equals("avi")の場合){ 0を返します。 } そうでない場合 (type.equals("mpg")) { 0を返します。 } そうでない場合 (type.equals("wmv")) { 0を返します。 } そうでない場合 (type.equals("3gp")) { 0を返します。 } そうでない場合 (type.equals("mov")) { 0を返します。 } そうでない場合 (type.equals("mp4")) { 0を返します。 } そうでない場合 (type.equals("asf")) { 0を返します。 } そうでない場合 (type.equals("asx")) { 0を返します。 } そうでない場合 (type.equals("flv")) { 0を返します。 } // ffmpeg が解析できないファイル形式 (wmv9、rm、rmvb など) の場合、 // 最初に他のツール (mencoder) を使用して avi (ffmpeg が解析できる) 形式に変換できます。 そうでない場合 (type.equals("wmv9")) { 1 を返します。 } そうでない場合 (type.equals("rm")) { 1 を返します。 } そうでない場合 (type.equals("rmvb")) { 1 を返します。 } 9を返します。 } プライベートブールチェックファイル(文字列パス) { ファイル file = new File(path); (!ファイル.isFile())の場合{ false を返します。 }それ以外 { true を返します。 } } // ffmpeg が解析できないファイル形式 (wmv9、rm、rmvb など) の場合は、まず他のツール (mencoder) を使用して、それらを avi (ffmpeg が解析できる) に変換できます。 プライベート文字列processAVI(int型) { リスト<String, String> = 新しい java.util.ArrayList(); commend.add(mencoderpath); PATHを追加します。 commend.add("-oac"); commend.add("mp3lame"); commend.add("-lameopts"); commend.add("preset=64"); commend.add("-ovc"); commend.add("xvid"); commend.add("-xvidencopts"); commend.add("ビットレート=600"); commend.add("-of"); commend.add("avi"); commend.add("-o"); commend.add(ビデオフォルダ + ファイル名 + ".avi"); // コマンドタイプ: mencoder 1.rmvb -oac mp3lame -lameoptspreset=64 -ovc xvid // -xvidencopts ビットレート=600 -of avi -ormvb.avi 試す { ProcessBuilder ビルダー = newProcessBuilder(); ビルダー.command(commend); プロセス p =builder.start(); p を待機します。 ビデオフォルダー + ファイルの実名 + ".avi" を返します。 } キャッチ (例外 e) { e.printStackTrace(); null を返します。 } } // ffmpeg が解析できる形式: (asx、asf、mpg、wmv、3gp、mp4、mov、avi、flv など) プライベートブール値processFLV(String oldfilepath) { if (!checkfile(PATH)) { System.out.println(oldfilepath+ " はファイルではありません"); false を返します。 } リスト<String, String> = 新しい java.util.ArrayList(); ffmpegpathを追加します。 commend.add("-i"); command.add(古いファイルパス); commend.add("-ab"); commend.add("64"); commend.add("-acodec"); commend.add("mp3"); commend.add("-ac"); commend.add("2"); commend.add("-ar"); commend.add("22050"); commend.add("-b"); commend.add("230"); commend.add("-r"); commend.add("24"); commend.add("-y"); commend.add(flvフォルダー + ファイル名 + ".flv"); 試す { ProcessBuilder ビルダー = newProcessBuilder(); 文字列 cmd =commend.toString(); ビルダー.command(commend); //builder.redirectErrorStream(true); プロセス p =builder.start(); p を待機します。 p.destroy(); ファイルを削除します(古いファイルパス)。 true を返します。 } キャッチ (例外 e) { e.printStackTrace(); false を返します。 } } パブリック int doWaitFor(プロセス p) { 入力ストリーム in = null; 入力ストリームエラー=null; int exitValue = -1; // pisが終了したら呼び出し元に返されます 試す { System.out.println("来る"); in = p.getInputStream(); エラー =p.getErrorStream(); boolean finished = false; //p が終了したら true に設定する (!終了)しながら{ 試す { (in.available() > 0) の場合 { // システムコールの出力を印刷する 文字 c = new Character((char) in.read()); システム出力をprint(c); } (err.available() > 0) の場合 { // システムコールの出力を印刷する 文字 c = new Character((char) err.read()); システム出力をprint(c); } //プロセスにexitValueを問い合わせます。プロセスが // 終了していない場合は、IllegalThreadStateException が発生します // がスローされます。終了した場合はフォールスルーして // 変数finishedはtrueに設定されます。 exitValue = p.exitValue(); 完了 = true; } キャッチ(IllegalThreadStateException e) { // プロセスはまだ終了していません。 // CPUサイクルを節約するために少しスリープします スレッド.currentThread().sleep(500); } } } キャッチ (例外 e) { // 予期しない例外です。デバッグのために出力します... System.err.println("doWaitFor();: 予期しない例外 - " + e.getMessage(); ついに 試す { if(in!=null) { in.close(); } } キャッチ (IOException e) { System.out.println(e.getMessage()); } if(エラー!=null) { 試す { エラー.close(); } IOException をキャッチします。 System.out.println(e.getMessage()); } } } // 完了ステータスを呼び出し元に返す exitValue を返します。 } パブリック void deleteFile(String filepath) { ファイル file = new File(filepath); if (PATH.equals(ファイルパス)) { if (file.delete()) { System.out.println("ファイル" + ファイルパス + "削除済み"); } } それ以外 { if (file.delete()) { System.out.println("ファイル" + ファイルパス + "削除済み"); } ファイル filedelete2 = newFile(PATH); (filedelete2.delete()) の場合{ System.out.println("ファイル" + PATH + "削除済み"); } } } パブリック文字列sumTime(long ms) { 整数 ss = 1000; 長いmi = ss * 60; 長さ hh = mi * 60; 長いdd = hh * 24; 長い日 = ms / dd; 長い時間 = (ms - 日 * dd) / hh; 長い分 = (ms - 日 * dd - 時間 * hh) /mi; 長秒 = (ms - 日 * dd - 時間 * hh - 分 * mi) / ss; long milliSecond = ms - 日 * dd - 時間 * hh - 分 * mi - 秒 * ss; 文字列 strDay = day < 10 ? "0" +day + "day" : "" + day + "day"; 文字列 strHour = hour < 10 ? "0"+ hour + "hour" : "" + hour + "hour"; 文字列 strMinute = minute < 10 ?"0" + minute + "分" : "" + minute + "分"; 文字列 strSecond = second < 10 ?"0" + second + "seconds" : "" + second + "seconds"; 文字列 strMilliSecond = milliSecond< 10 ? "0" + milliSecond : "" +ミリ秒; strMilliSecond = ミリ秒 <100 ? "0" + strMilliSecond + "ミリ秒" : "" +strMilliSecond + "ミリ秒"; strDay + " " + strHour + ":" + strMinute+ ":" + strSecond + " " を返します +strミリ秒; } } ご質問がありましたら、メッセージを残すか、コミュニティに参加して話し合いましょう。お読みいただきありがとうございます。お役に立てれば幸いです。このサイトをサポートしていただき、ありがとうございます。 以下もご興味があるかもしれません:
|
>>: Alibaba Cloud ESC サーバー シングルノード MySQL の Docker デプロイメント
プロジェクトでは https サービスを使用する必要があるため、Alibaba Cloud では無料...
この記事は、4G メモリ システム用の MySQL 構成ファイル ソリューションです (主に Inn...
まず、docker に openssh-server をインストールします。インストールが完了したら...
コードをコピーコードは次のとおりです。 li {幅:300px; 高さ:23px; 行の高さ:24p...
1. 原因公式の cerbot は面倒すぎます。野生の成長よりもさらに悪い acme.sh の使用は...
基礎1. スキャフォールディングを使用してプロジェクトを作成し、開始する1.1 足場を設置する: n...
<br />百度百科事典の正式版がついにオンラインになりました。2年間の「テスト版」の帽...
問題の説明Windows Server 2012 R2 または Windows Server 201...
ドラッグ アンド ドロップ API は、ドラッグ可能な要素を HTML に追加し、ドラッグ可能な豊富...
この記事は主にPostgreSQLマテリアライズドビューのプロセス分析について紹介します。サンプルコ...
IE6 で CSS スタイルの div または li の背景のタイリングや境界の破壊を解決するには、...
テーブル構造を設計する場合、数値型は最も一般的な型の 1 つですが、数値型をうまく使用するのは想像す...
関連記事:初心者が学ぶ HTML タグ (4)導入された HTML タグは、必ずしも XHTML 仕...
本日ご紹介するのは、jQuery を使用してシンプルなカルーセルを実装する方法です。実装の原則は次の...
成果を達成する実装コードhtml <div>123WORDPRESS.COM</d...