Java で ffmpeg を呼び出してビデオ形式を flv に変換する方法の詳細な説明

Java で ffmpeg を呼び出してビデオ形式を flv に変換する方法の詳細な説明

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ミリ秒;

}
}

ご質問がありましたら、メッセージを残すか、コミュニティに参加して話し合いましょう。お読みいただきありがとうございます。お役に立てれば幸いです。このサイトをサポートしていただき、ありがとうございます。

以下もご興味があるかもしれません:
  • Javaはffmpegを呼び出してビデオを変換します
  • Java+Windows+ffmpegでビデオ変換機能を実現
  • Javaを使用してffmpegを呼び出してビデオ変換を実現する方法
  • オープンソースプロジェクトJAVAE2を使用してビデオ形式を変換する

<<:  Reactのようなフレームワークをゼロから作成する

>>:  Alibaba Cloud ESC サーバー シングルノード MySQL の Docker デプロイメント

推薦する

Alibaba CloudがCloud Shieldから無料のSSL証明書(https)を申請

プロジェクトでは https サービスを使用する必要があるため、Alibaba Cloud では無料...

MySql 最適化のための my.ini 中国語構成スキームの詳細な説明: InnoDB、4GB メモリ、および複数のクエリ

この記事は、4G メモリ システム用の MySQL 構成ファイル ソリューションです (主に Inn...

dockerでsshd操作を有効にする

まず、docker に openssh-server をインストールします。インストールが完了したら...

行間隔が広い場合の解決策(IE では 5 ピクセル多い)

コードをコピーコードは次のとおりです。 li {幅:300px; 高さ:23px; 行の高さ:24p...

Docker で Let's Encrypt から永久無料 SSL 証明書を取得する方法

1. 原因公式の cerbot は面倒すぎます。野生の成長よりもさらに悪い acme.sh の使用は...

React+Ant Design開発環境をセットアップするための実装手順

基礎1. スキャフォールディングを使用してプロジェクトを作成し、開始する1.1 足場を設置する: n...

Baidu百科事典UIの開発動向について議論する

<br />百度百科事典の正式版がついにオンラインになりました。2年間の「テスト版」の帽...

Vue で HTML 5 ドラッグ アンド ドロップ API を使用する方法

ドラッグ アンド ドロップ API は、ドラッグ可能な要素を HTML に追加し、ドラッグ可能な豊富...

PostgreSQL マテリアライズドビュープロセス分析

この記事は主にPostgreSQLマテリアライズドビューのプロセス分析について紹介します。サンプルコ...

IE6 で CSS スタイルの div または li の背景のタイリングと境界の破損を解決する方法

IE6 で CSS スタイルの div または li の背景のタイリングや境界の破壊を解決するには、...

MySQLの数値型自動増分における落とし穴

テーブル構造を設計する場合、数値型は最も一般的な型の 1 つですが、数値型をうまく使用するのは想像す...

HTML チュートリアル: よく使われる HTML タグのコレクション (5)

関連記事:初心者が学ぶ HTML タグ (4)導入された HTML タグは、必ずしも XHTML 仕...

jQuery を使用してカルーセル効果を実装する

本日ご紹介するのは、jQuery を使用してシンプルなカルーセルを実装する方法です。実装の原則は次の...

CSS3で実装されたテキストポップアップ効果

成果を達成する実装コードhtml <div>123WORDPRESS.COM</d...