You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在API 21设备上使用API 27的MediaMetadataRetriever.getFrameAtTime方法?

Solution for Precise Frame Extraction on API 21+ Without API 27+ MediaMetadataRetriever Behavior

Hey there! Totally get your frustration here—needing precise frame extraction (not just the nearest keyframe) on older Android APIs while supporting a wide user base is a tricky spot. Let’s walk through a couple of reliable approaches that work for API 21 and above:

Option 1: Use FFmpeg (Most Straightforward)

FFmpeg is a powerful multimedia tool that lets you extract exact frames regardless of keyframe positions, and it works seamlessly on Android API 21+. Here’s how to implement it:

  • Integrate an FFmpeg wrapper for Android: Use a popular wrapper library like FFmpegAndroid (you can find it via standard Android dependency repositories). Add the dependency to your app-level build.gradle file.
  • Run the FFmpeg command asynchronously: Since frame extraction is CPU-heavy, always execute it on a background thread (like using Coroutines, WorkManager, or a dedicated thread). The command you’ll need looks like this:
    ffmpeg -ss 00:00:02.5 -i /path/to/your/video.mp4 -vframes 1 -q:v 2 /path/to/output/frame.jpg
    
    • -ss 00:00:02.5: Specifies the exact timestamp (in HH:MM:SS.mmm format) you want to extract.
    • -i /path/to/your/video.mp4: The input MP4 file path.
    • -vframes 1: Tells FFmpeg to extract just one frame.
    • -q:v 2: Sets output image quality (lower number = higher quality, 2 is a great balance).
  • Handle the output: Once the command finishes, load the output JPG file into your app’s UI (remember to switch back to the main thread for UI updates).

Option 2: Use ExoPlayer’s Frame Extraction API

Google’s ExoPlayer library includes a FrameExtractor class that supports precise frame extraction on API 21+. It’s a great choice if you’re already using ExoPlayer, or prefer a native Android solution over FFmpeg:

  • Add ExoPlayer dependencies: Include the necessary modules in your build.gradle (e.g., exoplayer-core).
  • Implement the frame extractor: Here’s a simplified code snippet to get you started:
    val frameExtractor = FrameExtractor()
    val dataSourceFactory = DefaultDataSourceFactory(context, "YourAppName")
    val mediaItem = MediaItem.fromUri(Uri.parse("/path/to/your/video.mp4"))
    
    frameExtractor.setDataSource(
        dataSourceFactory,
        mediaItem,
        object : FrameExtractor.Listener {
            override fun onFrameExtracted(frame: Bitmap, presentationTimeUs: Long) {
                // Use the extracted frame here (switch to UI thread if updating views)
                frameExtractor.release() // Clean up resources when done
            }
            
            override fun onError(error: Exception) {
                // Handle extraction errors
                frameExtractor.release()
            }
        }
    )
    
    // Set the exact timestamp you want (in microseconds)
    frameExtractor.seekTo(targetTimeUs)
    frameExtractor.start()
    
    • Always call release() when finished to free up memory.
    • Run this code on a background thread to avoid blocking the UI.

Option 3: Manual MP4 Parsing (Advanced)

If you have deep expertise in multimedia coding, you can parse the MP4 file yourself to extract non-keyframes. This involves:

  • Reading the MP4 container structure to locate the video track.
  • Parsing H.264 NAL units to identify P-frames/B-frames and decode them using Android’s MediaCodec.
  • Handling the dependency chain between frames (since non-keyframes rely on previous frames to decode).

This approach is not recommended for most developers—it’s time-consuming, error-prone, and requires handling countless edge cases.

Key Notes

  • Always perform frame extraction on a background thread to prevent ANRs.
  • Ensure your app has the necessary permissions (e.g., READ_EXTERNAL_STORAGE if accessing files from external storage).
  • Test thoroughly on API 21 devices to confirm you’re getting the exact frame, not just a keyframe.

内容的提问来源于stack exchange,提问作者Jeff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:05:50