FFmpegMediaMetadataRetriever

repository·master·Indexed 23 days ago

https://github.com/wseemann/ffmpegmediametadataretriever

A reimplementation of Android's MediaMetadataRetriever that uses FFmpeg as a backend. It provides enhanced support for various media formats, protocols (including URLs such as http, https, mms, mmsh, and rtmp), and metadata extraction capabilities. The library includes a build system called ffmpeg-android-maker to automate the assembly of FFmpeg shared libraries and executables for Android ABIs including armeabi-v7a, arm64-v8a, x86, and x86_64.

Tokens
1.7K
Snippets
2
Records
9
Agent score
33%

What's inside FFmpegMediaMetadataRetriever

  1. Customize FFmpeg build and external libraries

    master

    You can tune the FFmpeg build process through several methods:

    • Vanilla Build: The master branch builds a 'vanilla' version containing all default components and shared libraries.
    • Customized Build (Example): The media-file branch provides an example of a tuned build that only compiles necessary functionality, resulting in much smaller output binaries.
    • External Libraries: You can add arbitrary external libraries that FFmpeg supports. This requires specifying how the source code is downloaded and how the build operation is performed.
    • FFmpeg Version: You can override the default FFmpeg version (currently 7.1.1) by passing arguments to the script.
    • Script Arguments: Various arguments are available to tune specific features, such as selecting desired ABIs or the Android platform version (default is API 19, though NDK r23 allows API 16, and some libraries like libvpx require API 21).
  2. Build FFmpegMediaMetadataRetriever from source

    master

    Building the library from source is currently only supported on Unix or Linux systems.

    Prerequisites

    • Android Studio Narwhal 2025.1.2 or higher
    • Android NDK r27 or higher

    Build Steps

    1. Execute the project update command in the root directory (ensure /path/to/android_sdk/tools is in your PATH):
      android update project --path .
    2. Open the newly created local.properties file and configure your SDK and NDK paths:
      sdk.dir=<path to SDK>
      ndk.dir=<path to NDK>
      Example:
      sdk.dir=/Users/wseemann/Library/Android/sdk
      ndk.dir=/Users/wseemann/Library/Android/sdk/ndk/27.1.12297006
    3. In Android Studio, highlight the core module in the project explorer and select Build -> Make Module 'core'. This will compile the library and the native FFmpeg binaries.
  3. Set up ffmpeg-android-maker requirements

    master

    To use ffmpeg-android-maker, you must have the Android SDK and NDK installed on your host system. The script requires you to define the following environment variables pointing to the absolute paths of your installations:

    • ANDROID_SDK_HOME: Absolute path to your Android SDK.
    • ANDROID_NDK_HOME: Absolute path to your Android NDK.

    Note on NDK Version: The script requires at least Android NDK r23. While your main Android project might use a different version, the build process itself depends on r23 or higher.

  4. Install FFmpegMediaMetadataRetriever via Gradle

    master

    To use FFmpegMediaMetadataRetriever in your Android project, add the core and native dependencies to your build.gradle file.

    By default, you can include the unified native dependency:

    dependencies {
        implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-core:1.0.23'
        implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-native:1.0.23'
    }

    If you want to reduce your APK size by supporting only specific ABIs, you can replace the unified native dependency with individual architecture-specific dependencies:

    dependencies {
        implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-core:1.0.23'
        implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-native-armeabi-v7a:1.0.23'
        implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-native-x86:1.0.23'
        implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-native-x86_64:1.0.23'
        implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-native-arm64-v8a:1.0.23'
    }
  5. Build FFmpeg for Android using ffmpeg-android-maker

    master

    The ffmpeg-android-maker.sh script automates the process of downloading FFmpeg source code and assembling it for Android. It produces:

    1. Shared libraries (*.so files) and header files (*.h files) in an output directory, optimized for seamless integration into Android projects.
    2. Executables (ffmpeg and ffprobe) in the build directory, which can be used in an Android terminal or embedded directly into an app.

    Supported Android ABIs:

    • armeabi-v7a (with NEON)
    • arm64-v8a
    • x86
    • x86_64

    You can restrict the build to specific ABIs using script arguments.

    Supported Host OS:

    • macOS & Linux: Supported natively via terminal.
    • Windows 10: Use WSL (e.g., Ubuntu 20.04 LTS). You must manually install the Linux versions of the Android SDK and NDK within the WSL subsystem.
    • Any OS: Use Docker to execute the script in a controlled environment.
  6. Retrieve media metadata and frames with FFmpegMediaMetadataRetriever

    master

    The FFmpegMediaMetadataRetriever class provides a unified interface for retrieving frame and metadata from media files using FFmpeg. It supports URLs (unlike the standard Android MediaMetadataRetriever) and various protocols including file, http, https, mms, mmsh, and rtmp.

    To use it, instantiate the class, set the data source, extract the desired metadata keys, and ensure you call release() when finished to free resources.

    FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
    mmr.setDataSource(mUri);
    mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ALBUM);
    mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ARTIST);
    Bitmap b = mmr.getFrameAtTime(2000000, FFmpegMediaMetadataRetriever.OPTION_CLOSEST); // frame at 2 seconds
    byte [] artwork = mmr.getEmbeddedPicture();
    
    mmr.release();