2011-08-11 4 views
1

私はAsp.Net C#Framework 4を使用しており、現在はビデオ変換アプリケーションを開発中です。私はffmpegを使ってアップロードされた全てのフォーマットをflvに変換しています。私はmp4からflvに直接変換しようとしているときに遭遇した問題のために、最初にアップロードされたファイルをmpgに変換してからflvに変換しています。しかし、mpgファイルへの変換プロセスが完了すると、ffmpegはフリーズします。タスクマネージャを実行してプロセスリストをチェックすると、CPUリソースを使用しないでそこに立つだけです。私がffmpegプロセスをタスクマネージャから直接終了すると、mpgからflvに変換され、ファイル(jpg)をプレビューしてスムーズに動作する他のプロセスが実行されます。最初のプロセスがフリーズするため、Webページのファイルアップロードフォームからアップロードしようとすると、2番目のプロセスを開始できません。私は今から何か応答をありがとう。ここに私のコードは次のとおりです。ffmpeg.exeフリーズ

 string duration = "00:00:00"; 

     //converting video 
     Process ffmpeg; 
     ffmpeg = new Process(); 

     // convert to mpg 1st 
     ffmpeg.StartInfo.Arguments = " -i \"" + Server.MapPath("static/user/vid/") + videolink + "\" -f mpeg -b 300k -ac 2 -ab 128k -ar 44K \"" + Server.MapPath("static/user/vid/") + mpglink + "\""; 
     ffmpeg.StartInfo.FileName = Page.MapPath("bin/ffmpeg.exe"); 
     ffmpeg.StartInfo.CreateNoWindow = true; 
     ffmpeg.StartInfo.UseShellExecute = false; 
     ffmpeg.StartInfo.RedirectStandardOutput = true; 
     ffmpeg.StartInfo.RedirectStandardError = true; 
     ffmpeg.Start(); 

     ffmpeg.WaitForExit(); 
     ffmpeg.Close(); 


     // mpg 2 flv 
     ffmpeg = new Process(); 
     ffmpeg.StartInfo.Arguments = " -i \"" + Server.MapPath("static/user/vid/") + mpglink + "\" -f flv -s 624x352 \"" + Server.MapPath("static/user/vid/") + flvlink + "\""; 
     ffmpeg.StartInfo.FileName = Page.MapPath("bin/ffmpeg.exe"); 
     ffmpeg.StartInfo.CreateNoWindow = true; 
     ffmpeg.StartInfo.UseShellExecute = false; 
     ffmpeg.StartInfo.RedirectStandardOutput = true; 
     ffmpeg.StartInfo.RedirectStandardError = true; 
     ffmpeg.Start(); 

     ffmpeg.BeginOutputReadLine(); 
     string error = ffmpeg.StandardError.ReadToEnd(); 
     ffmpeg.WaitForExit(); 

     try 
     { 
      duration = error.Substring(error.IndexOf("Duration: ") + 10, 8); 
     } 
     catch 
     { 
     } 

     if (ffmpeg.ExitCode != 0) 
     { 
      ltrUpload.Text = "<div class=\"resultbox-negative\" id=\"divResult\">Problem occured during upload process. Error code: " + error + "<br>" + "</div>"; 
      return; 
     } 
     ffmpeg.Close(); 


     // generate preview image 
     ffmpeg.StartInfo.Arguments = " -i \"" + Server.MapPath("static/user/vid/") + flvlink + "\" -s 624x352 -ss 00:00:03 -an -vframes 1 -f image2 -vcodec mjpeg \"" + Server.MapPath("static/user/vid/") + flvlink.Replace(".flv", ".jpg") + "\""; 
     ffmpeg.StartInfo.FileName = Page.MapPath("bin/ffmpeg.exe"); 
     ffmpeg.StartInfo.CreateNoWindow = true; 
     ffmpeg.StartInfo.UseShellExecute = false; 
     ffmpeg.StartInfo.RedirectStandardOutput = true; 
     ffmpeg.StartInfo.RedirectStandardError = true; 
     ffmpeg.Start(); 
     ffmpeg.WaitForExit(); 
     ffmpeg.Close(); 

     // deleting original file and mpg 
     FileInfo fi = new FileInfo(Server.MapPath("static/user/vid/") + videolink); 
     if (fi.Exists) fi.Delete(); 
     fi = new FileInfo(Server.MapPath("static/user/vid/") + mpglink); 
     if (fi.Exists) fi.Delete(); 
+0

あなたの問題には実際には関係しませんが(しかしそれは助けになるかもしれません) - あなたは本当にこのような長期のプロセスをWindowsサービスのような別のアプリケーションに移すべきです。それはフォルダを見て、マルチスレッドの変換などを行うことができます。Webアプリケーションはこの種のものにはあまり適していません。 –

答えて

3

私は、これは非常に古い質問ですけど、誰かがいるため、Googleの検索でここに得れば、答えは以下の通りです:

あなたが読まなければならないだろうあなたがそれを必要としない場合でも、最初のffmpegプロセスのリダイレクトされたエラー出力。リダイレクトされたエラー出力を読み込まないと、デッドロックが発生します。これは、プログラムがプロセスが終了するまで待機するため、プロセスは埋め込まれたエラー出力ストリームが読み込まれるまで待機します。あなたはそれを見ることができますhere

// convert to mpg 1st 
    ffmpeg.StartInfo.Arguments = " -i \"" + Server.MapPath("static/user/vid/") + videolink + "\" -f mpeg -b 300k -ac 2 -ab 128k -ar 44K \"" + Server.MapPath("static/user/vid/") + mpglink + "\""; 
    ffmpeg.StartInfo.FileName = Page.MapPath("bin/ffmpeg.exe"); 
    ffmpeg.StartInfo.CreateNoWindow = true; 
    ffmpeg.StartInfo.UseShellExecute = false; 
    ffmpeg.StartInfo.RedirectStandardOutput = true; 
    ffmpeg.StartInfo.RedirectStandardError = true; 
    ffmpeg.Start(); 

    // Use asynchronous read operations on at least one of the streams. 
    // Reading both streams synchronously would generate another deadlock. 
    ffmpeg.BeginOutputReadLine(); 
    string tmpErrorOut = ffmpeg.StandardError.ReadToEnd(); 

    ffmpeg.WaitForExit(); 
    ffmpeg.Close(); 

したがって、2番目のffmpegプロセスと同じように、リダイレクトされたエラーと出力ストリームを読み取る必要があります。

画像プレビュー部分を生成する場合も同じです!

+0

私にとって、 'ffmpeg.StandardError.ReadToEnd();' –

+1

という行でフリーズします。非同期メソッド 'ffmpeg.BeginOutputReadLine (); '? –

+0

最後に、コードスニペットをコピー/ペーストするだけで、うまくいきました。ありがとうございました。 –

-1
private bool ReturnVideo(string fileName) 
{ 
    string html = string.Empty; 
    //rename if file already exists 

    int j = 0; 
    string AppPath; 
    string inputPath; 
    string outputPath; 
    string imgpath; 
    AppPath = Request.PhysicalApplicationPath; 
    //Get the application path 
    inputPath = AppPath + "Upload\\Videos\\OriginalVideo"; 
    //Path of the original file 
    outputPath = AppPath + "Upload\\Videos\\ConvertVideo"; 
    //Path of the converted file 
    imgpath = AppPath + "Upload\\Videos\\Thumbs"; 
    //Path of the preview file 
    string filepath = Server.MapPath("../Upload/Videos/OriginalVideo/" + fileName); 
    while (File.Exists(filepath)) 
    { 
    j = j + 1; 
    int dotPos = fileName.LastIndexOf("."); 
    string namewithoutext = fileName.Substring(0, dotPos); 
    string ext = fileName.Substring(dotPos + 1); 
    fileName = namewithoutext + j + "." + ext; 
    filepath = Server.MapPath("../Upload/Videos/OriginalVideo/" + fileName); 
    } 
    try 
    { 
    this.fileuploadImageVideo.SaveAs(filepath); 
    } 
    catch 
    { 
    return false; 
    } 
    string outPutFile; 
    outPutFile = "../Upload/Videos/OriginalVideo/" + fileName; 
    int i = this.fileuploadImageVideo.PostedFile.ContentLength; 
    System.IO.FileInfo a = new System.IO.FileInfo(Server.MapPath(outPutFile)); 
    while (a.Exists == false) 
    { } 
    long b = a.Length; 
    while (i != b) 
    { } 

    string cmd = " -i \"" + inputPath + "\\" + fileName + "\" \"" + outputPath + "\\" + fileName.Remove(fileName.IndexOf(".")) + ".flv" + "\""; 
    ConvertNow(cmd); 
    ViewState["fileName"] = fileName.Remove(fileName.IndexOf(".")) + ".wmv"; 
    string imgargs = " -i \"" + inputPath + "\\" + fileName.Remove(fileName.IndexOf(".")) + ".wmv" + "\" -f image2 -ss 1 -vframes 1 -s 280x200 -an \"" + imgpath + "\\" + fileName.Remove(fileName.IndexOf(".")) + ".jpg" + "\""; 
    ConvertNow(imgargs); 

    return true; 
} 

private void ConvertNow(string cmd) 
{ 
    string exepath; 
    string AppPath = Request.PhysicalApplicationPath; 
    //Get the application path 
    exepath = AppPath + "ffmpeg.exe"; 
    System.Diagnostics.Process proc = new System.Diagnostics.Process(); 
    proc.StartInfo.FileName = exepath; 
    //Path of exe that will be executed, only for "filebuffer" it will be "wmvtool2.exe" 
    proc.StartInfo.Arguments = cmd; 
    //The command which will be executed 
    proc.StartInfo.UseShellExecute = false; 
    proc.StartInfo.CreateNoWindow = true; 
    proc.StartInfo.RedirectStandardOutput = false; 
    proc.Start(); 

    while (proc.HasExited == false) 
    { } 
} 

if (fileuploadImageVideo.HasFile) 
{ 
    ReturnVideo(this.fileuploadImageVideo.FileName.ToString()); 

    string filename = fileuploadImageVideo.PostedFile.FileName; 
    fileuploadImageVideo.SaveAs(Server.MapPath("../upload/Video/"+filename)); 
    objfun.Video = filename ; 
} 
+1

こんにちは@Munish、ようこそ。あなたの答えが元の質問になぜ答えるのかを説明するのに役立ちます – DaveHogan

+0

Downvote:いいえ説明 –