YY-EVA Android

repository·main·Indexed 42 days ago

https://github.com/yylive/yyeva-android

A lightweight, high-performance, cross-platform MP4 animation player using Native OpenGL ES rendering, specifically designed for gift animations in Android apps. It supports dynamic content replacement via IEvaFetchResource, playback control through IEvaAnimView (EvaAnimView and EvaAnimViewV3), and configuration via EvaAnimConfig and OptionParams (introduced in v2.0.0-beta).

Tokens
3.8K
Snippets
11
Records
12
Agent score
54%

What's inside YY-EVA

  1. Install YY-EVA Android via Gradle

    main

    To use YY-EVA in your Android project, add the JitPack repository to your allprojects block and then add the dependency to your dependencies block.

    For the stable version:

    implementation 'com.github.yylive.YYEVA-Android:yyeva:1.0.17'

    For the 2.0.0-beta version:

    implementation 'com.github.yylive.YYEVA-Android:yyeva:2.0.0-beta'
    allprojects {
    	repositories {
    		maven { url 'https://jitpack.io' }
    	}
    }
    
    dependencies {
    	implementation 'com.github.yylive.YYEVA-Android:yyeva:1.0.17'
    }
  2. Install YYEVA-Android via Gradle

    main

    To use YYEVA-Android in your project, add the JitPack repository to your allprojects block in build.gradle, then add the dependency for the version you wish to use.

    Note: Version 2.0.0-beta introduces changes in how playback is configured (using OptionParams).

    // 1. Add JitPack to repositories
    allprojects {
    	repositories {
    		maven { url 'https://jitpack.io' }
    	}
    }
    
    // 2. Add dependency
    // For stable version:
    dependencies {
    	implementation 'com.github.yylive.YYEVA-Android:yyeva:1.0.17'
    }
    
    // For 2.0.0-beta version:
    dependencies {
        implementation 'com.github.yylive.YYEVA-Android:yyeva:2.0.0-beta'
    }
  3. Understand EvaFrame, EvaFrameSet, and EvaFrameAll data structures

    main

    YY-EVA uses a hierarchical data structure to represent animation frames and sets of frames. This hierarchy allows for organized access to frame data, including source IDs, Z-order, and coordinate rectangles for rendering and output.

    • EvaFrame: Represents a single animation frame. It contains:

      • srcId: The source effect ID.
      • z: The Z-order index.
      • frame: A PointRect representing the render frame.
      • mFrame: A PointRect representing the output frame.
      • mt: Mask rotation angle (v2 only supports 0 or 90 degrees).
    • EvaFrameSet: A collection of EvaFrame objects belonging to a specific animation index (index).

    • EvaFrameAll: A complete collection of all frames, organized as a SparseArray<EvaFrameSet> where the key is the frame set's index.

  4. Implement IEvaFetchResource to replace MP4 elements

    main

    The IEvaFetchResource interface allows you to intercept and replace elements (images and text) within the MP4 animation. This is useful for dynamic content like user avatars or personalized text.

    Implement this interface to handle resource loading, video mode alignment, and playback settings like mute or start point.

    interface IEvaFetchResource {
        // Get image (Note: Bitmap.Config.ALPHA_8 is not supported due to OpenGL compatibility issues)
        fun setImage(resource: EvaResource, result:(Bitmap?) -> Unit)
    
        // Get text
        fun setText(resource: EvaResource, result:(String?) -> Unit)
    
        // Notify resource release
        fun releaseSrc(resources: List<EvaResource>)
    
        // Set playback speed
        fun setVideoFps(fps: Int, speed: Float = 1.0f)
    
        // Set video mode (alignment of alpha/rgb regions)
        fun setVideoMode(mode: Int)
    
        // Set start position in milliseconds
        fun setStartPoint(startPoint: Long)
    
        // Set mute status
        fun setMute(isMute: Boolean)
    
        // Set if MP4 is normal
        fun setNormalMp4(isNormalMp4: Boolean)
    
        // Set if it should stay on the last frame
        fun setLastFrame(isSetLastFrame: Boolean)
    
        // Set logging
        fun setLog(log: IELog)
    }
  5. Configure playback using OptionParams (v2.0.0-beta)

    main

    In version 2.0.0-beta, you can use the OptionParams class to configure various playback settings:

    • frameRate: Set the animation frame rate (default: 30).
    • playCount: Number of times to play.
    • isMute: Whether the audio is muted.
    • isRemoteService: Whether to use a multi-process mode.
    • mp4Address: Path to the MP4 resource.
    • scaleType: Scaling behavior (1: Crop center, 2: Full screen stretch, 3: Original size).
    • filterType: High-definition algorithm (e.g., hermite or lagrange).
    class OptionParams {
        var frameRate = 30
        var playCount = 1
        var isMute = false
        var isRemoteService = true
        var mp4Address = ""
        var scaleType = 1
        var filterType = ""
    }
  6. Use the IEvaAnimView interface to play animations

    main

    YY-EVA provides two main view types for rendering animations:

    • EvaAnimView: Use this for SurfaceView.
    • EvaAnimViewV3: Use this for TextureView.

    You interact with these views through the IEvaAnimView interface. Key methods include:

    • startPlay(file: File): Plays an animation from a file.
    • startPlay(assetManager: AssetManager, assetsPath: String): Plays an animation from the Android assets folder.
    • stopPlay(): Stops playback.
    • setLoop(playLoop: Int): Sets the playback loop count.
    • setVideoFps(fps: Int, speed: Float = 1.0f): Sets the frame rate and playback speed.
    • setMute(isMute: Boolean): Toggles mute.
    • setLastFrame(isSetLastFrame: Boolean): Determines if the animation should stay on the last frame.
    // Example usage of IEvaAnimView methods
    interface IEvaAnimView {
        fun startPlay(file: File)
        fun startPlay(assetManager: AssetManager, assetsPath: String)
        fun stopPlay()
        fun isRunning(): Boolean
        fun setLoop(playLoop: Int)
        fun setBgImage(bg: Bitmap)
        fun setVideoFps(fps: Int, speed: Float = 1.0f)
        fun setVideoMode(mode: Int)
        fun setStartPoint(startPoint: Long)
        fun setMute(isMute: Boolean)
        fun setNormalMp4(isNormalMp4: Boolean)
        fun setLastFrame(isSetLastFrame: Boolean)
        fun setLog(log: IELog)
    }
  7. Use IEvaAnimView to play animations

    main

    The IEvaAnimView interface is the primary way to control animation playback. Depending on your requirements, you can use EvaAnimView (for SurfaceView) or EvaAnimViewV3 (for TextureView).

    interface IEvaAnimView {
        // Play from a File
        fun startPlay(file: File)
    
        // Play from Assets
        fun startPlay(assetManager: AssetManager, assetsPath: String)
    
        // Stop playback
        fun stopPlay()
    
        // Check if currently running
        fun isRunning(): Boolean
    
        // Set loop count
        fun setLoop(playLoop: Int)
    
        // Set background image
        fun setBgImage(bg: Bitmap)
    }
  8. Implement IEvaFetchResource for custom resource loading

    main

    If you need to provide custom images or text to the animation engine, implement the IEvaFetchResource interface. This allows the engine to fetch assets asynchronously:

    • setImage(resource: EvaResource, result: (Bitmap?) -> Unit): Fetches an image. Note: Bitmap.Config.ALPHA_8 is currently not supported due to OpenGL compatibility issues on some devices.
    • setText(resource: EvaResource, result: (String?) -> Unit): Fetches text content.
    • releaseSrc(resources: List<EvaResource>): Notifies the engine that specific resources can be released.
    interface IEvaFetchResource {
        fun setImage(resource: EvaResource, result:(Bitmap?) -> Unit)
        fun setText(resource: EvaResource, result:(String?) -> Unit)
        fun releaseSrc(resources: List<EvaResource>)
    }
  9. Configure playback with OptionParams (v2.0.0-beta)

    main

    In version 2.0.0-beta, use the OptionParams class to configure playback behavior instead of direct interface calls. This includes settings for frame rate, mute status, scaling, and high-definition filters.

    class OptionParams {
        var frameRate = 30
        var playCount = 1
        var isMute = false
        var isRemoteService = true  // Use multi-process
        var mp4Address = ""
        var scaleType = 1   // 1 => Crop center, 2 => Full screen stretch, 3 => Original size
        var filterType = "" // High-definition algorithms: "hermite" or "lagrange"
    }
  10. Configure video modes with setVideoMode

    main

    The setVideoMode(mode: Int) method allows you to control how the alpha and RGB channels of the MP4 are aligned. Use the following integer constants:

    ConstantDescription
    1 (VIDEO_MODE_SPLIT_HORIZONTAL)Video split horizontally (alpha left, rgb right)
    2 (VIDEO_MODE_SPLIT_VERTICAL)Video split vertically (alpha top, rgb bottom)
    3 (VIDEO_MODE_SPLIT_HORIZONTAL_REVERSE)Video split horizontally (rgb left, alpha right)
    4 (VIDEO_MODE_SPLIT_VERTICAL_REVERSE)Video split vertically (rgb top, alpha bottom)
    5 (YYEVAColorRegion_AlphaMP4_alphaHalfRightTop)Video split vertically (rgb top, alpha bottom 1/4)
    const val VIDEO_MODE_SPLIT_HORIZONTAL = 1
    const val VIDEO_MODE_SPLIT_VERTICAL = 2
    const val VIDEO_MODE_SPLIT_HORIZONTAL_REVERSE = 3
    const val VIDEO_MODE_SPLIT_VERTICAL_REVERSE = 4
    const val YYEVAColorRegion_AlphaMP4_alphaHalfRightTop = 5
  11. Configure animation playback with EvaAnimConfig

    main

    The EvaAnimConfig class is used to parse and manage the configuration for animation playback, typically loaded from a JSON file (often referred to as effectmp4json). It defines the video dimensions, RGB and Alpha frame positions, dynamic element (effect) properties, and per-frame positioning data.

    To use it, create an instance of EvaAnimConfig and call the parse(json: JSONObject) method. If parsing succeeds, the object will be populated with the video's metadata, effects, and frame data. If parsing fails, the object will fall back to default configurations.

    val config = EvaAnimConfig()
    val success = config.parse(jsonConfigObject)
    if (success) {
        // Use config.width, config.height, config.effects, etc.
    }
  12. JSON schema for EvaAnimConfig

    main

    The EvaAnimConfig expects a JSON structure containing descript, effect, and datas objects. This schema defines how the animation engine interprets video frames and dynamic elements.

    Root Object Structure

    • descript: Video metadata (dimensions, version, frame positions).
    • effect: An array of dynamic element mask descriptions.
    • datas: An array of per-frame positioning data.

    Descript Object

    • width: Output video width.
    • height: Output video height.
    • isEffect: Boolean indicating if it is a dynamic element video.
    • version: Plugin version.
    • rgbFrame: [x, y, w, h] position for the RGB area.
    • alphaFrame: [x, y, w, h] position for the alpha area.
    • fps: Frames per second.
    • haAudio: Boolean for audio presence.
    • hasBg: Boolean for background presence.

    Effect Object (within effect array)

    • effectWidth: Width of the dynamic element.
    • effectHeight: Height of the dynamic element.
    • effectId: Unique index ID for the element.
    • effectTag: String tag for the element.
    • effectType: Type of element ("txt" or "img").
    • fontColor: Hex color (only for "txt").
    • fontSize: Font size (only for "txt").
    • textAlign: Text alignment (e.g., "center").
    • scaleMode: Scaling behavior.

    Datas Object (within datas array)

    • frameIndex: The specific frame index.
    • data: An array of Data objects for that frame.

    Data Object (within data array)

    • renderFrame: [x, y, w, h] position on the canvas.
    • effectId: ID of the effect being rendered.
    • outputFrame: [x, y, w, h] position in the video area.
    {
      "descript": {
        "width": 1808,
        "height": 1008,
        "isEffect": 1,
        "version": 1,
        "rgbFrame": [0, 0, 900, 1000],
        "alphaFrame": [900, 0, 450, 500],
        "fps": 30
      },
      "effect": [{
        "effectWidth": 700,
        "effectHeight": 1049,
        "effectId": 1,
        "effectTag": "a1",
        "effectType": "txt",
        "fontColor": "#ffffff",
        "fontSize": 13,
        "textAlign": "center"
      }],
      "datas": [{
        "frameIndex": 0,
        "data": [{
          "renderFrame": [10, 10, 100, 100],
          "effectId": 1,
          "outputFrame": [20, 20, 80, 80]
        }]
      }]
    }