我想检索视频的所有帧(mp4)

问题描述 投票:0回答:1

我想提取项目原始文件夹中的所有视频帧(mp4)。

val videoUri = Uri.parse("android.resource://" + packageName + "/" + R.raw.video_h)

captureVideoFrames(this@OutsideCamActivity, videoUri)

我可以使用下面给出的函数获取帧,但是速度很慢并且丢失帧。

private fun captureAndDisplayFrames(videoUri: Uri) {
        lifecycleScope.launch(Dispatchers.IO) {
            val retriever = MediaMetadataRetriever()
            try {
                retriever.setDataSource(this@OutsideCamActivity, videoUri)

                // Get the video duration
                val videoDuration =
                    retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLong() ?: 0L

                var currentPosition = 0L
                // Capture frames at regular intervals
                while (currentPosition < videoDuration) {
                    // Extract frame at the current position
                    val frame: Bitmap? = retriever.getFrameAtTime(currentPosition * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC)

                    // Check if the frame was successfully retrieved
                    if (frame != null) {
                        // Update the ImageView on the main thread
                        withContext(Dispatchers.Main) {
                            imgOutH.setImageBitmap(frame)
                        }
                    } else {
                        Log.e("FrameExtraction", "No frame found at time: $currentPosition")
                    }

                    // Increment position (e.g., by 1 second or as per your requirement)
                    currentPosition += 1000 // Move to the next second
                }

            } catch (e: IllegalArgumentException) {
                Log.e("FrameExtraction", "Invalid video source: ${e.message}")
            } catch (e: IllegalStateException) {
                Log.e("FrameExtraction", "Retriever not configured properly: ${e.message}")
            } catch (e: Exception) {
                Log.e("FrameExtraction", "Error retrieving frame: ${e.message}")
            } finally {
                retriever.release() // Always release the retriever resource
            }
        }
    }

我所做的是捕获帧并设置在 ImageView 中。

我的要求不是在 ImageView 中设置,而是对图像进行一些处理,该图像也可以正常工作。捕获所有帧时出现问题。

android kotlin
1个回答
0
投票

MediaMetadataRetriever.OPTION_CLOSEST_SYNC
只为您提供 I 帧。但部分帧(通常是大多数)将会丢失。

您可以使用

MediaMetadataRetriever.OPTION_CLOSEST
来获取所有帧,但这很慢。

更有效的方法是将 MediaCodecMediaExtractor 一起使用。

© www.soinside.com 2019 - 2024. All rights reserved.