簡體   English   中英

使用 MediaMetadataRetriever 從視頻中獲取所有幀

[英]Get all frames from video using MediaMetadataRetriever

我正在嘗試使用MediaMetadataRetrievergetFrameAt()方法從視頻中獲取所有幀。 使用FFMPEG ,我得到了以下信息:

  1. 視頻幀數:234幀

  2. 視頻持續時間(以毫秒為單位):90000

     int counter = 0; long mVideoDuration = 9000; for (long i = 0; i < mVideoDuration * 1000; i += 1000) { Bitmap thumbnail = mMediaMetadataRetriever.getFrameAtTime(i); }

上面的代碼不起作用,它循環了將近8944次,這太多了,我不想得到所有這些幀,我只想得到234幀。

getFrameAtIndex()工作得很好,但由於 API 級兼容性,我想讓它與getFrameAt()方法一起工作

要使用 getFrameeAtTime() 獲取幀,您必須知道視頻中每一幀的時間。 您可以粗略地計算出,如果您已經通過獲取幀時間(持續時間/幀)知道幀數,則可以對其使用 math.ceil() 方法並將其作為增量器。 但是,您必須檢查是否讀取了最后一幀,因為您不能總是獲得准確的幀時間,因為它們往往有很多小數位,這會導致錯誤表示為浮點數。 例如,60fps 視頻的幀時間為 16+1/3 毫秒。 其具有無限小數位。 此外,如果您的視頻幀率過高,此方法甚至根本不起作用,因為在這種情況下,由 math.ceil() 完成的匯總可能會導致足夠大的余量以跳過幀。 准確地說,此方法僅在以下情況下有效:

(math.ceil(frameTime)-frameTime)⋅frameCount<frameTime

我希望,到現在為止你已經知道這是一個非常糟糕的主意,你應該使用另一種方法來獲取單個幀。 但是,這里仍然是一個實現:

int lastTime;
long mVideoDuration = 9000;
mVideoDuration*=1000;
int frameTime=math.ceil(mVideoDuration/frameCount)
for(int i =0, i<=mVideoDuration, i+=frameTime){
    Bitmap thumbnail = mMediaMetadataRetriever.getFrameAtTime(i);
    lastTime=i;
}
if (lastTime<mVideoDuration){
   mMediaMetadataRetriever.getFrameAtTime(mVideoDuration);
}

當然,這已經假設,

(math.ceil(frameTime)-frameTime)⋅frameCount<frameTime

給出。 而且我不能保證 declaframeTime 會產生正確的值,因為我不知道內部如何處理十進制除法並且它完全有可能由於浮點溢出而導致問題

您可以使用getFramesAtIndex(int frameIndex, int numFrames)而不是getFrameAt() ,它將返回包含請求的視頻幀的位圖列表。

此方法類似於 getFramesAtIndex(int, int, MediaMetadataRetriever.BitmapParams),只是將使用 MediaMetadataRetriever.BitmapParams 的默認值。 參數: frameIndex – 要檢索的第一個視頻幀的從 0 開始的索引。 幀索引必須是有效幀的索引。 可以通過 METADATA_KEY_VIDEO_FRAME_COUNT 鍵查詢可用於檢索的幀總數。 numFrames – 要檢索的連續視頻幀數。 必須是正值。 stream 必須至少包含從 frameIndex 開始的 numFrames 幀。 返回:包含請求的視頻幀的位圖列表。 如果檢索失敗,返回的數組包含的幀可能少於請求的幀。 拋出: IllegalStateException – 如果容器不包含視頻或圖像序列。 IllegalArgumentException – 如果 frameIndex 或 numFrames 無效,或者 stream 不包含至少從 frameIndex 開始的 numFrames。 另見:getFrameAtIndex(int, MediaMetadataRetriever.BitmapParams), getFrameAtIndex(int), getFramesAtIndex(int, int, MediaMetadataRetriever.BitmapParams)

關於numFrames ,您可以通過這種方式獲得幀數:

m_mediaMetadataRetriever = new MediaMetadataRetriever();
m_mediaMetadataRetriever.setDataSource(getApplicationContext(), your_video_path);
int numFrames = Integer.parseInt(m_mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_FRAME_COUNT));

暫無
暫無

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

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