ffmpeg Progress Bar-نسبة الترميز في PHP




regex parsing (2)

لقد كتبت نظامًا كاملاً في PHP وباش على الخادم لتحويل مقاطع الفيديو وتدفقها في HTML5 على VPS. يتم التحويل بواسطة ffmpeg في الخلفية ويتم إخراج المحتويات إلى block.txt .

بعد الاطلاع على المشاركات التالية:

يمكن ffmpeg تظهر شريط التقدم؟

و

شريط ترميز الفيديو ffmpeg

من بين أمور أخرى ، لا يمكنني العثور على مثال عملي.

أحتاج إلى الحصول على التقدم المشفر حاليًا كنسبة مئوية.

أول مشاركة قمت بربطها أعلاه تعطي:

$log = @file_get_contents('block.txt');

preg_match("/Duration:([^,]+)/", $log, $matches);
list($hours,$minutes,$seconds,$mili) = split(":",$matches[1]);
$seconds = (($hours * 3600) + ($minutes * 60) + $seconds);
$seconds = round($seconds);

$page = join("",file("$txt"));
$kw = explode("time=", $page);
$last = array_pop($kw);
$values = explode(' ', $last);
$curTime = round($values[0]);
$percent_extracted = round((($curTime * 100)/($seconds)));

echo $percent_extracted;

المتغير $ percent_extracted يكرر صفر ، وبما أن الرياضيات ليست نقطة قوية ، فأنا لا أعرف كيف أتقدم هنا.

هنا خط واحد من إخراج ffmpeg من block.txt (إذا كان مفيدًا)

time = 00: 19: 25.16 bitrate = 823.0kbits / s frame = 27963 fps = 7 q = 0.0 size = 117085kB time = 00: 19: 25.33 bitrate = 823.1kbits / s frame = 27967 fps = 7 q = 0.0 size = 117085kB time = 00: 19: 25.49 bitrate = 823.0kbits / s frame = 27971 fps = 7 q = 0.0 size = 117126kB

الرجاء مساعدتي في إخراج هذه النسبة المئوية ، وبمجرد الانتهاء من ذلك ، يمكنني إنشاء شريط التقدم الخاص بي. شكر.


إذا كان javascript يقوم بتحديث شريط التقدم الخاص بك ، فيمكن أن يقوم javascript بتنفيذ الخطوة 2 مباشرة ":

[هذا المثال يتطلب dojo ]

dojo php: بدء التحويل وكتابة الحالة إلى ملف نصي - بناء جملة مثال:

exec("ffmpeg -i path/to/input.mov path/to/output.flv 1>path/to/output.txt 2>&1");

بالنسبة للجزء الثاني ، نحتاج فقط إلى javascript لقراءة الملف. يستخدم المثال التالي dojo.request لـ AJAX ، ولكن يمكنك استخدام jQuery أو vanilla أو أي شيء أيضًا:

[2] js: grab the progress from the file:

var _progress = function(i){
    i++;
    // THIS MUST BE THE PATH OF THE .txt FILE SPECIFIED IN [1] : 
    var logfile = 'path/to/output.txt';

/* (example requires dojo) */

request.post(logfile).then( function(content){
// AJAX success
    var duration = 0, time = 0, progress = 0;
    var result = {};

    // get duration of source
    var matches = (content) ? content.match(/Duration: (.*?), start:/) : [];
    if( matches.length>0 ){
        var rawDuration = matches[1];
        // convert rawDuration from 00:00:00.00 to seconds.
        var ar = rawDuration.split(":").reverse();
        duration = parseFloat(ar[0]);
        if (ar[1]) duration += parseInt(ar[1]) * 60;
        if (ar[2]) duration += parseInt(ar[2]) * 60 * 60;

        // get the time 
        matches = content.match(/time=(.*?) bitrate/g);
        console.log( matches );

        if( matches.length>0 ){
            var rawTime = matches.pop();
            // needed if there is more than one match
            if (lang.isArray(rawTime)){ 
                rawTime = rawTime.pop().replace('time=','').replace(' bitrate',''); 
            } else {
                rawTime = rawTime.replace('time=','').replace(' bitrate','');
            }

            // convert rawTime from 00:00:00.00 to seconds.
            ar = rawTime.split(":").reverse();
            time = parseFloat(ar[0]);
            if (ar[1]) time += parseInt(ar[1]) * 60;
            if (ar[2]) time += parseInt(ar[2]) * 60 * 60;

            //calculate the progress
            progress = Math.round((time/duration) * 100);
        }

        result.status = 200;
        result.duration = duration;
        result.current  = time;
        result.progress = progress;

        console.log(result);

        /* UPDATE YOUR PROGRESSBAR HERE with above values ... */

        if(progress==0 && i>20){
            // TODO err - giving up after 8 sec. no progress - handle progress errors here
            console.log('{"status":-400, "error":"there is no progress while we tried to encode the video" }'); 
            return;
        } else if(progress<100){ 
            setTimeout(function(){ _progress(i); }, 400);
        }
    } else if( content.indexOf('Permission denied') > -1) {
        // TODO - err - ffmpeg is not executable ...
        console.log('{"status":-400, "error":"ffmpeg : Permission denied, either for ffmpeg or upload location ..." }');    
    } 
},
function(err){
// AJAX error
    if(i<20){
        // retry
        setTimeout(function(){ _progress(0); }, 400);
    } else {
        console.log('{"status":-400, "error":"there is no progress while we tried to encode the video" }');
        console.log( err ); 
    }
    return; 
});
}
setTimeout(function(){ _progress(0); }, 800);

حسنًا ، لقد وجدت ما أحتاجه - ونأمل أن يساعد هذا شخصًا آخر أيضًا!

أولاً وقبل كل شيء ، تريد إخراج بيانات ffmpeg إلى ملف نصي على الخادم.

ffmpeg -i path/to/input.mov -vcodec videocodec -acodec audiocodec path/to/output.flv 1> block.txt 2>&1

لذا ، فإن إخراج ffmpeg هو block.txt. الآن في PHP ، دعونا نفعل ذلك!

$content = @file_get_contents('../block.txt');

if($content){
    //get duration of source
    preg_match("/Duration: (.*?), start:/", $content, $matches);

    $rawDuration = $matches[1];

    //rawDuration is in 00:00:00.00 format. This converts it to seconds.
    $ar = array_reverse(explode(":", $rawDuration));
    $duration = floatval($ar[0]);
    if (!empty($ar[1])) $duration += intval($ar[1]) * 60;
    if (!empty($ar[2])) $duration += intval($ar[2]) * 60 * 60;

    //get the time in the file that is already encoded
    preg_match_all("/time=(.*?) bitrate/", $content, $matches);

    $rawTime = array_pop($matches);

    //this is needed if there is more than one match
    if (is_array($rawTime)){$rawTime = array_pop($rawTime);}

    //rawTime is in 00:00:00.00 format. This converts it to seconds.
    $ar = array_reverse(explode(":", $rawTime));
    $time = floatval($ar[0]);
    if (!empty($ar[1])) $time += intval($ar[1]) * 60;
    if (!empty($ar[2])) $time += intval($ar[2]) * 60 * 60;

    //calculate the progress
    $progress = round(($time/$duration) * 100);

    echo "Duration: " . $duration . "<br>";
    echo "Current Time: " . $time . "<br>";
    echo "Progress: " . $progress . "%";

}

هذا يخرج النسبة المئوية من الوقت المتبقي.

يمكنك الحصول على هذا كقطعة واحدة من النص مرددًا إلى صفحة ، ومن صفحة أخرى يمكنك تنفيذ طلب AJAX باستخدام jQuery للحصول على هذا النص وإخراجه في div ، على سبيل المثال ، للتحديث على صفحتك كل 10 ثواني. :)





ffmpeg