# Video extension (/en/realtime-media/marketplace/build/build-your-own-extension/video-filter)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

The video filters you create are easily integrated into apps to supply visual effects and background processing.

<_PlatformTabsGroup groupMode="structured" canonicalPlatform="web" platforms="[&#x22;android&#x22;,&#x22;ios&#x22;,&#x22;macos&#x22;,&#x22;web&#x22;,&#x22;windows&#x22;,&#x22;electron&#x22;,&#x22;flutter&#x22;,&#x22;react-native&#x22;,&#x22;unity&#x22;]" showTabs="true">
  <_PlatformPanel platform="android">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="web" platform="android" />

    ## Understand the tech [#understand-the-tech]

    A video filter accesses video data when it is captured from the user's local device, modifies it, then plays the updated data to local and remote video channels.

    ![Video extension pipeline](https://assets-docs.agora.io/images/video-sdk/extension-video-filter.png)

    A typical transmission pipeline consists of a chain of procedures, including capture, pre-processing, encoding, transmitting, decoding, post-processing, and playback. To modify the voice or video data in the transmission pipeline, video extensions are inserted into either the pre-processing or post-processing stage.

    ## Prerequisites [#prerequisites]

    * Android Studio 4.1 or higher.
    * Android SDK API Level 24 or higher.
    * A mobile device that runs Android 4.1 or higher.
    * A project to develop in.

    ## Project setup [#project-setup]

    In order to integrate an extension into your project:

    * Follow the SDK setup flow in [Quickstart - integrate an extension](../../quickstart-integrate.mdx).
    * Prepare the Android project structure and Gradle dependencies required for the extension package.

    You are now ready to develop your extension.

    ## Create a video extension [#create-a-video-extension]

    After encapsulating the filter into an extension, you need to register and package it into a `.aar` or `.so` file, and submit it together with a file that contains the extension name, vendor name, and filter name to Agora.

    ### Package the extension [#package-the-extension]

    1. Register the extension.

       Register the extension with the `REGISTER_AGORA_EXTENSION_PROVIDER` macro in `AgoraExtensionProviderEntry.h`. Use this macro at the entrance of the extension implementation. When the SDK loads the extension, this macro automatically registers it to the SDK. For example:

       ```cpp
       REGISTER_AGORA_EXTENSION_PROVIDER(ByteDance, agora::extension::ExtensionProvider);
       ```

    2. Link the `libagora-rtc-sdk-jni.so` file.

       In `CMakeLists.txt`, specify the path to save the `libagora-rtc-sdk-jni.so` file in the downloaded SDK package according to the following table:

       | File                             | Path                                                                     |
       | -------------------------------- | ------------------------------------------------------------------------ |
       | 64-bit `libagora-rtc-sdk-jni.so` | `AgoraWithByteDanceAndroid/agora-bytedance/src/main/agoraLibs/arm64-v8a` |
       | 32-bit `libagora-rtc-sdk-jni.so` | `AgoraWithByteDanceAndroid/agora-bytedance/src/main/agoraLibs/arm64-v7a` |

    3. Provide extension information.

       Create a `.java` or `.md` file to provide the following information:

       * `EXTENSION_NAME`: The name of the target link library used in `CMakeLists.txt`. For example, for a `.so` file named `libagora-bytedance.so`, the `EXTENSION_NAME` should be `agora-bytedance`.
       * `EXTENSION_VENDOR_NAME`: The name of the extension provider, which is used for registering in the `agora-bytedance.cpp` file.
       * `EXTENSION_FILTER_NAME`: The name of the filter, which is defined in `ExtensionProvider.h`.

    ## Test your implementation [#test-your-implementation]

    * Run functional and performance tests.
    * Validate the extension listing in Agora's test environment.
    * Prepare the public integration document and update it after end-to-end verification.

    You are then ready to [Publish your extension](../publish-extension.md).

    ## Reference [#reference]

    * [RtcEngineConfig.addExtension](/en/api-reference/rtc/android/class-and-enum/classes/class-rtcengineconfig)
    * [enableExtension](/en/api-reference/rtc/android/video/pre-and-post-processing/extensions)
    * [setExtensionProperty](/en/api-reference/rtc/android/video/pre-and-post-processing/extensions)
    * [IMediaExtensionObserver](/en/api-reference/rtc/android/class-and-enum/interfaces/class-imediaextensionobserver)

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="ios">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="web" platform="ios" />

    ## Understand the tech [#understand-the-tech-1]

    A video filter accesses video data when it is captured from the user's local device, modifies it, then plays the updated data to local and remote video channels.

    ![Video extension pipeline](https://assets-docs.agora.io/images/video-sdk/extension-video-filter.png)

    A typical transmission pipeline consists of a chain of procedures, including capture, pre-processing, encoding, transmitting, decoding, post-processing, and playback. To modify the voice or video data in the transmission pipeline, video extensions are inserted into either the pre-processing or post-processing stage.

    ## Prerequisites [#prerequisites-1]

    * Xcode 12.0 or higher.
    * A device running iOS 9.0 or higher.
    * A project to develop in.

    ## Project setup [#project-setup-1]

    * Follow the iOS SDK setup flow in [Quickstart - integrate an extension](../../quickstart-integrate.mdx).
    * Prepare the project structure, frameworks, and signing settings needed for your extension package.

    ## Create a video extension [#create-a-video-extension-1]

    Package the extension as an iOS framework or xcframework, register it with the SDK, and provide the metadata Agora needs for Marketplace integration.

    ## Reference [#reference-1]

    * [RTC iOS API reference](../../../../api-reference/rtc/ios.md)
    * [RTC iOS API reference](../../../../api-reference/rtc/ios.md)

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="macos">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="web" platform="macos" />

    ## Understand the tech [#understand-the-tech-2]

    A video filter accesses video data when it is captured from the user's local device, modifies it, then plays the updated data to local and remote video channels.

    ![Video extension pipeline](https://assets-docs.agora.io/images/video-sdk/extension-video-filter.png)

    A typical transmission pipeline consists of a chain of procedures, including capture, pre-processing, encoding, transmitting, decoding, post-processing, and playback. To modify the voice or video data in the transmission pipeline, video extensions are inserted into either the pre-processing or post-processing stage.

    ## Prerequisites [#prerequisites-2]

    * Xcode 12.0 or higher.
    * A device running macOS 10.11 or higher.
    * An Apple developer account.
    * A project to develop in.

    ## Project setup [#project-setup-2]

    * Follow the macOS SDK setup flow in [Quickstart - integrate an extension](../../quickstart-integrate.mdx).
    * Prepare the framework packaging, code signing, and runtime loading flow for your extension.

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="web">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="web" platform="web" />

    ## Understand the tech [#understand-the-tech-3]

    A video filter accesses video data when it is captured from the user's local device, modifies it, then plays the updated data to local and remote video channels.

    ![Video extension pipeline](https://web-cdn.agora.io/docs-files/1648464654193)

    A typical transmission pipeline consists of a chain of procedures, including capture, pre-processing, encoding, transmitting, decoding, post-processing, and playback. To modify the voice or video data in the transmission pipeline, video extensions are inserted into either the pre-processing or post-processing stage.

    ## Prerequisites [#prerequisites-3]

    * A [supported browser](../../reference/supported-platforms.mdx).
    * Physical media input devices such as a camera and a microphone.
    * A JavaScript package manager such as [npm](https://www.npmjs.com/package/npm).
    * A project to develop in.

    ## Project setup [#project-setup-3]

    * Start from the Web flow in [Quickstart - integrate an extension](../../quickstart-integrate.mdx).
    * Prepare your extension package, bundler integration, and runtime registration flow.

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="windows">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="web" platform="windows" />

    ## Understand the tech [#understand-the-tech-4]

    A video filter accesses video data when it is captured from the user's local device, modifies it, then plays the updated data to local and remote video channels.

    ![Video extension pipeline](https://assets-docs.agora.io/images/video-sdk/extension-video-filter.png)

    A typical transmission pipeline consists of a chain of procedures, including capture, pre-processing, encoding, transmitting, decoding, post-processing, and playback. To modify the voice or video data in the transmission pipeline, video extensions are inserted into either the pre-processing or post-processing stage.

    ## Prerequisites [#prerequisites-4]

    * A device running Windows 7 or higher.
    * Microsoft Visual Studio 2017 or higher.
    * C#.
    * A project to develop in.

    ## Project setup [#project-setup-4]

    * Follow the Windows SDK setup flow in [Quickstart - integrate an extension](../../quickstart-integrate.mdx).
    * Prepare the extension DLL packaging and loading flow.

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="electron">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="web" platform="electron" />

    ## Understand the tech [#understand-the-tech-5]

    A video filter accesses video data when it is captured from the user's local device, modifies it, then plays the updated data to local and remote video channels.

    ## Prerequisites [#prerequisites-5]

    * Physical media input devices such as a camera and a microphone.
    * A JavaScript package manager such as [npm](https://www.npmjs.com/package/npm).
    * A project to develop in.

    ## Project setup [#project-setup-5]

    * Follow the Electron SDK setup flow in [Quickstart - integrate an extension](../../quickstart-integrate.mdx).
    * Prepare the native extension packaging and runtime loading flow.

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="flutter">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="web" platform="flutter" />

    **We are still developing extensions for this platform. The docs will magically appear here as soon as it is released.**

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="react-native">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="web" platform="react-native" />

    **We are still developing extensions for this platform. The docs will magically appear here as soon as it is released.**

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="unity">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="web" platform="unity" />

    **We are still developing extensions for this platform. The docs will magically appear here as soon as it is released.**

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>
</_PlatformTabsGroup>
