2

.net ffmpegラッパーhttp://www.mediasoftpro.comを使用してバックグラウンドビデオ処理を実装し、プログレスバー表示を使用して、処理されるビデオの量を計算し、情報をWebページに送信してプログレスバーインジケーターを更新しました。一度に1つのプロセスのみが機能する場合は正常に機能しますが、2つの同時プロセス(2つの異なるコンピューターから同時に2つのビデオ公開を開始する)の場合、プログレスバーは突然進行状況を混合します。これは、静的オブジェクトを使用して単一インスタンスの情報をプログレスバーに適切に送信するコードです。

static string FileName = "grey_03";
protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        if (Request.Params["file"] != null)
        {
            FileName = Request.Params["file"].ToString();
        }
    }
}
public static double ProgressValue = 0;
public static MediaHandler _mhandler = new MediaHandler();

[WebMethod]
public static string EncodeVideo()
{
    // MediaHandler _mhandler = new MediaHandler();
    string RootPath = HttpContext.Current.Server.MapPath(HttpContext.Current.Request.ApplicationPath);
    _mhandler.FFMPEGPath = HttpContext.Current.Server.MapPath("~\\ffmpeg_july_2012\\bin\\ffmpeg.exe");
    _mhandler.InputPath = RootPath + "\\contents\\original";
    _mhandler.OutputPath = RootPath + "\\contents\\mp4";
    _mhandler.BackgroundProcessing = true;
    _mhandler.FileName = "Grey.avi";
    _mhandler.OutputFileName =FileName;
    string presetpath = RootPath + "\\ffmpeg_july_2012\\presets\\libx264-ipod640.ffpreset";
    _mhandler.Parameters = " -b:a 192k -b:v 500k -fpre \"" + presetpath + "\"";
    _mhandler.OutputExtension = ".mp4";
    _mhandler.VCodec = "libx264";
    _mhandler.ACodec = "libvo_aacenc";
    _mhandler.Channel = 2;
    _mhandler.ProcessMedia();
    return _mhandler.vinfo.ErrorCode.ToString();
}

[WebMethod]
public static string GetProgressStatus()
{
    return Math.Round(_mhandler.vinfo.ProcessingCompleted, 2).ToString();
    // if vinfo.processingcomplete==100, then you can get complete information from vinfo object and store it in database and perform other processing.
}

これは、毎秒ごとにプログレスバーの表示を更新するjquery関数です。

$(function () {
         $("#vprocess").on({
             click: function (e) {
                 ProcessEncoding();
                 var IntervalID = setInterval(function () {
                     GetProgressValue(IntervalID);
                 }, 1000);
                 return false;
             }
         }, '#btn_process');

     });
     function GetProgressValue(intervalid) {
         $.ajax({
             type: "POST",
             url: "concurrent_03.aspx/GetProgressStatus",
             data: "{}",
             contentType: "application/json; charset=utf-8",
             dataType: "json",
             success: function (msg) {
                 // Do something interesting here.
                 $("#pstats").text(msg.d);
                 $("#pbar_int_01").attr('style', 'width: ' + msg.d + '%;');
                 if (msg.d == "100") {
                     $('#pbar01').removeClass("progress-danger");
                     $('#pbar01').addClass("progress-success");
                     if (intervalid != 0) {
                         clearInterval(intervalid);
                     }
                     FetchInfo();
                 }
             }
         });
     }

この問題は、静的なmediahandlerオブジェクトが原因で発生します

public static MediaHandler _mhandler = new MediaHandler();

プログレスバーをそのプロセスに正確に属する値で更新するために、2つの並行プロセス情報を互いに分離しておく方法が必要です。

4

1 に答える 1

2

ここで誤解があると思います。

変数を使用しているためstatic、同時実行の問題が発生しています。これは、ASP.NET では、static変数はアプリ プールがリサイクルされるまで AppDomain ごとに 1 回であるため、すべての要求で共有されるためです。

サービスが終了したかどうかを確認するために使用できる WCF エンドポイントを公開する必要があります。このサービスはキューを処理し、キューffmpeg内の各アイテムに対してプログラムを呼び出す必要があります。ページを呼び出すユーザーの数については言及していませんが、サーバーが一度に処理できるアイテムの数をより簡単に制御できるように、このように設計することをお勧めします。また、ASP.NET ではなくサービス コンテキストでプロセスを実行しているため、問題が少なくなります。

于 2012-07-17T15:09:07.083 に答える