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

React Native中如何使用Play Asset Delivery分离视频资源

在React Native中使用Play Asset Delivery分离并调用视频资源

一、配置Android端Play Asset Delivery结构

Play Asset Delivery是Android专属功能,需先在Android项目中配置资源结构和依赖:

  • 在app/src/main下创建assets目录,按交付类型创建子目录(如on-demand/videos),将视频文件放入对应路径(例:assets/on-demand/videos/demo.mp4)
  • 修改app/build.gradle,添加Asset Delivery依赖和资产包声明:
android {
    // ... 其他配置
    assetPacks = [":on-demand-videos"] // 资产包名称,需与后续模块对应
}

dependencies {
    // ... 其他依赖
    implementation 'com.google.android.play:asset-delivery:2.2.0'
}
  • 在项目根目录创建资产包模块(如on-demand-videos),其build.gradle配置如下:
plugins {
    id 'com.android.asset-pack'
}

assetPack {
    packName = "on-demand-videos" // 与app/build.gradle中的assetPacks对应
    dynamicDelivery {
        deliveryType = "on-demand" // 可选值:install-time/fast-follow/on-demand
    }
}

二、编写React Native原生桥接模块

React Native无原生支持Play Asset Delivery,需自定义原生模块实现资源路径获取:

  1. 创建Kotlin模块类PlayAssetDeliveryModule.kt:
package com.your_app_package_name;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;
import com.google.android.play.core.assetpacks.AssetPackManager;
import com.google.android.play.core.assetpacks.AssetPackManagerFactory;
import com.google.android.play.core.assetpacks.AssetPackState;
import com.google.android.play.core.assetpacks.AssetPackStateUpdateListener;
import com.google.android.play.core.assetpacks.model.AssetPackStatus;
import java.io.File;
import kotlin.collections.Lists;

class PlayAssetDeliveryModule extends ReactContextBaseJavaModule {
    private AssetPackManager assetPackManager;

    PlayAssetDeliveryModule(ReactApplicationContext context) {
        super(context);
        assetPackManager = AssetPackManagerFactory.create(context);
    }

    @Override
    public String getName() {
        return "PlayAssetDelivery";
    }

    @ReactMethod
    public void getVideoPath(String videoName, Promise promise) {
        String packName = "on-demand-videos";
        // 检查资产包是否已下载完成
        assetPackManager.getPackStates(Lists.listOf(packName)).addOnCompleteListener(task -> {
            if (task.isSuccessful()) {
                AssetPackState state = task.getResult().get(packName);
                if (state != null && state.status() == AssetPackStatus.COMPLETED) {
                    String assetPath = new File(assetPackManager.getAssetsPath(packName), "videos/" + videoName).getAbsolutePath();
                    promise.resolve(assetPath);
                } else {
                    // 触发资产包下载并监听状态
                    assetPackManager.fetch(Lists.listOf(packName));
                    assetPackManager.registerListener(new AssetPackStateUpdateListener() {
                        @Override
                        public void onStateUpdate(AssetPackState updateState) {
                            if (updateState.packName().equals(packName)) {
                                if (updateState.status() == AssetPackStatus.COMPLETED) {
                                    String assetPath = new File(assetPackManager.getAssetsPath(packName), "videos/" + videoName).getAbsolutePath();
                                    promise.resolve(assetPath);
                                    assetPackManager.unregisterListener(this);
                                } else if (updateState.status() == AssetPackStatus.FAILED) {
                                    promise.reject("DOWNLOAD_FAILED", "Failed to download asset pack");
                                    assetPackManager.unregisterListener(this);
                                }
                            }
                        }
                    });
                }
            } else {
                promise.reject("STATE_CHECK_ERROR", "Failed to check asset pack state");
            }
        });
    }
}
  1. 创建包注册类PlayAssetDeliveryPackage.kt:
package com.your_app_package_name;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class PlayAssetDeliveryPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new PlayAssetDeliveryModule(reactContext));
        return modules;
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}
  1. 在MainApplication.kt中注册该包:
override fun getPackages(): List<ReactPackage> {
    return PackageList(this).packages.apply {
        add(PlayAssetDeliveryPackage())
    }
}

三、在JavaScript中调用原生模块获取并播放视频

通过NativeModules调用原生方法获取视频本地路径,再用react-native-video播放:

import { NativeModules, Platform } from 'react-native';
import Video from 'react-native-video';
import { useState } from 'react';

const { PlayAssetDelivery } = NativeModules;
const [videoSource, setVideoSource] = useState(null);

// 获取并播放视频的异步函数
const loadAndPlayVideo = async (videoFileName) => {
  if (Platform.OS !== 'android') {
    console.warn('Play Asset Delivery is Android-only');
    return;
  }
  try {
    const localPath = await PlayAssetDelivery.getVideoPath(videoFileName);
    setVideoSource({ uri: `file://${localPath}` });
  } catch (err) {
    console.error('Failed to load video:', err);
  }
};

// 使用示例:调用loadAndPlayVideo('demo.mp4')

渲染Video组件:

{videoSource && (
  <Video
    source={videoSource}
    style={{ width: '100%', height: 300 }}
    controls={true}
  />
)}

四、打包上传至Google Play

  • 生成App Bundle(.aab)而非APK,Play Asset Delivery仅支持Bundle格式
  • 在Google Play Console中确认资产包的交付类型配置与本地代码一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 23:30:49