簡體   English   中英

獲取 HTML5 視頻中的幀數

[英]Get frame numbers in HTML5 Video

我正在嘗試捕獲視頻的每個幀號,但看起來沒有辦法實現它。 所以我開始使用自己的時鍾來匹配視頻的幀數,但它們從不匹配,並且隨着視頻的進展,差異不斷增加。

請看看我的垃圾箱。 http://jsbin.com/dopuvo/4/edit

我已將幀號添加到 Adob​​e After Effect 視頻的每一幀中,以便我有更准確的差異信息。 視頻以 29.97fps 運行,並且 requestAnimationFrame 也設置為以相同的速率增加數量,但是我不確定這種差異來自哪里。

有時它們匹配,有時它們不匹配。 我也試過離線做,但我得到了相同的結果。 任何幫助。

為此,我在 github 上找到了一些東西。 https://github.com/allensarkisyan/VideoFrame

我已經在這個小提琴中實現了它: https : //jsfiddle.net/k0y8tp2v/

var currentFrame = $('#currentFrame');
var video = VideoFrame({
    id : 'video',
    frameRate: 25,
    callback : function(frame) {
        currentFrame.html(frame);
    }
});

$('#play-pause').click(function(){
    if(video.video.paused){
        video.video.play();
        video.listen('frame');
        $(this).html('Pause');
    }else{
        video.video.pause();
        video.stopListen();
        $(this).html('Play');
    }
});

編輯:將小提琴更新為新視頻,使其再次工作。

編輯:正如所指出的,視頻是 25fps,所以我更新了它,當我在那里時,它消除了對 jQuery 的依賴。
非 jQuery 版本:
https://jsfiddle.net/k0y8tp2v/1/

var currentFrame = document.getElementById('currentFrame');
var video = VideoFrame({
    id : 'video',
    frameRate: 25,
    callback : function(frame) {
        currentFrame.innerHTML = frame ;
    }
});

document.getElementById('play-pause').addEventListener('click', function(e){
    if(video.video.paused){
        video.video.play();
        video.listen('frame');
        e.target.innerHTML = 'Pause';
    }else{
        video.video.pause();
        video.stopListen();
        e.target.innerHTML = 'Play';
    }
});

問題在於setTimeout並不是真正可預測的,因此您無法確定每次運行您的函數時都恰好顯示了一個新幀。 每次更新幀顯示時都需要檢查視頻的currentTime並將其乘以幀速率。

這是一個工作示例: http : //jsbin.com/xarekice/1/edit它已關閉一幀,但看起來您可能在開頭有兩幀標記為“000000”。

您可能想要了解的有關視頻元素的一些事項:

  1. 正如您似乎已經發現的那樣,沒有可靠的方法來確定幀速率,因此您必須在其他地方發現它並對其進行硬編碼。 視頻指標有一些有趣的事情,但它們是非標准的,沒有得到廣泛支持,並且根據我的經驗,在確定實際幀速率方面完全無效。

  2. currentTime並不總是完全代表屏幕上的內容。 有時它會提前一點,尤其是在查找時(這就是為什么在我的 JSBin 中,我不會在您查找時更新框架)。

我相信currentTime在與實際視頻繪制不同的線程上更新,因此它的工作方式就像它自己的時鍾一樣一直在運行。 這是視頻想要的位置,不一定是它的位置。 所以你可以接近,但你需要對幀計算的結果進行四舍五入,偶爾,你可能會偏離一幀。

從 M83 開始,Chromium 有一個 requestVideoFrameCallback() API,它可能會解決您的問題。 您可以使用 mediaTime 獲得一致的時間戳,如此 Github issue 中所述 從那里,你可以嘗試這樣的事情:

var frameCounter = (time, metadata) => {
   let count = metadata.mediaTime * frameRate;
   console.log("Got frame: " + Math.round(count));

   // Capture code here.

   video.requestVideoFrameCallback(frameCounter);
}

video.requestVideoFrameCallback(frameCounter)

這只會在新幀上觸發,但您可能偶爾會錯過一個(您可以從metadata.presentedFrames計數中的不連續性中檢測到)。 您也可能在捕獲幀時稍晚(通常 16 毫秒,或者比視頻幀可用時晚一次調用window.requestAnimationFrame() )。

如果您對 API 的高級概述感興趣,請參閱博客文章,或者您可以查看API 的官方 github

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM