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

如何在React Native中集成并控制Android Kotlin视频播放器及原生Activity?

在React Native中集成并控制Kotlin编写的Android原生视频播放器Activity

下面是完整的实现步骤,涵盖从原生模块封装到JS层调用、双向控制的全流程:

1. 封装Kotlin原生模块

首先在Android项目的app/src/main/java/[你的包名]/modules下创建两个文件:

VideoPlayerModule.kt

这个模块负责处理React Native发来的指令,以及向JS层发送播放器状态:

import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.modules.core.DeviceEventManagerModule
import android.content.Intent

class VideoPlayerModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
    private var playerActivity: VideoPlayerActivity? = null

    override fun getName(): String = "VideoPlayerModule"

    // 启动视频播放器Activity
    @ReactMethod
    fun startPlayerActivity(videoUrl: String) {
        val intent = Intent(reactApplicationContext, VideoPlayerActivity::class.java)
        intent.putExtra("VIDEO_URL", videoUrl)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        reactApplicationContext.startActivity(intent)
    }

    // 发送播放指令
    @ReactMethod
    fun play() {
        playerActivity?.player?.play()
    }

    // 发送暂停指令
    @ReactMethod
    fun pause() {
        playerActivity?.player?.pause()
    }

    // 跳转至指定进度(单位:毫秒)
    @ReactMethod
    fun seekTo(position: Long) {
        playerActivity?.player?.seekTo(position)
    }

    // 设置播放器Activity引用,用于直接控制
    fun setPlayerActivity(activity: VideoPlayerActivity) {
        this.playerActivity = activity
    }

    // 向JS层发送播放器状态事件
    fun sendPlayerEvent(eventName: String, data: ReadableMap?) {
        reactApplicationContext
            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
            .emit(eventName, data)
    }
}

VideoPlayerPackage.kt

用于注册原生模块到React Native:

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

class VideoPlayerPackage : ReactPackage {
    override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
        val modules = ArrayList<NativeModule>()
        modules.add(VideoPlayerModule(reactContext))
        return modules
    }

    override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
        return emptyList()
    }
}

2. 配置视频播放器Activity

假设你已经有一个用Kotlin开发的VideoPlayerActivity,需要做以下调整:

在AndroidManifest.xml中注册Activity

<activity android:name=".VideoPlayerActivity"
          android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
          android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>

修改VideoPlayerActivity.kt,添加与RN模块的交互

在Activity的生命周期方法中绑定模块,并在播放器状态变化时发送事件:

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.facebook.react.bridge.Arguments
import com.yourpackage.modules.VideoPlayerModule

class VideoPlayerActivity : AppCompatActivity() {
    lateinit var player: YourVideoPlayer // 替换成你的Kotlin播放器实例
    private lateinit var videoPlayerModule: VideoPlayerModule

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_video_player)
        
        // 获取RN模块引用
        videoPlayerModule = reactApplicationContext.getNativeModule(VideoPlayerModule::class.java)
        videoPlayerModule.setPlayerActivity(this)

        // 初始化播放器并设置监听
        val videoUrl = intent.getStringExtra("VIDEO_URL")
        player = YourVideoPlayer(videoUrl)
        player.setOnPlaybackListener(object : PlaybackListener {
            override fun onPlay() {
                val event = Arguments.createMap()
                event.putString("status", "playing")
                videoPlayerModule.sendPlayerEvent("onPlayerStatusChange", event)
            }

            override fun onPause() {
                val event = Arguments.createMap()
                event.putString("status", "paused")
                videoPlayerModule.sendPlayerEvent("onPlayerStatusChange", event)
            }

            override fun onProgressUpdate(currentPosition: Long, duration: Long) {
                val event = Arguments.createMap()
                event.putDouble("currentPosition", currentPosition.toDouble())
                event.putDouble("duration", duration.toDouble())
                videoPlayerModule.sendPlayerEvent("onPlayerProgress", event)
            }
        })
    }

    override fun onDestroy() {
        super.onDestroy()
        player.release() // 释放播放器资源
        videoPlayerModule.setPlayerActivity(null)
    }
}

3. 在React Native JS层调用与监听

封装播放器工具类(VideoPlayer.js)

import { NativeModules, NativeEventEmitter } from 'react-native';

const { VideoPlayerModule } = NativeModules;
const videoPlayerEmitter = new NativeEventEmitter(VideoPlayerModule);

export const VideoPlayer = {
  // 启动原生播放器
  start: (videoUrl) => {
    VideoPlayerModule.startPlayerActivity(videoUrl);
  },
  // 播放
  play: () => {
    VideoPlayerModule.play();
  },
  // 暂停
  pause: () => {
    VideoPlayerModule.pause();
  },
  // 跳转进度
  seekTo: (position) => {
    VideoPlayerModule.seekTo(position);
  },
  // 监听播放器状态
  addStatusListener: (callback) => {
    return videoPlayerEmitter.addListener('onPlayerStatusChange', callback);
  },
  // 监听播放进度
  addProgressListener: (callback) => {
    return videoPlayerEmitter.addListener('onPlayerProgress', callback);
  }
};

在组件中使用

import React, { useEffect } from 'react';
import { View, Button, Text } from 'react-native';
import { VideoPlayer } from './VideoPlayer';

const App = () => {
  let statusListener = null;
  let progressListener = null;

  useEffect(() => {
    // 注册监听
    statusListener = VideoPlayer.addStatusListener((event) => {
      console.log('播放器状态:', event.status);
    });

    progressListener = VideoPlayer.addProgressListener((event) => {
      console.log('当前进度:', event.currentPosition, '总时长:', event.duration);
    });

    // 组件卸载时移除监听
    return () => {
      statusListener?.remove();
      progressListener?.remove();
    };
  }, []);

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Button title="打开播放器" onPress={() => VideoPlayer.start('https://your-video-url.mp4')} />
      <Button title="播放" onPress={() => VideoPlayer.play()} style={{ marginTop: 10 }} />
      <Button title="暂停" onPress={() => VideoPlayer.pause()} style={{ marginTop: 10 }} />
      <Button title="跳转到10秒" onPress={() => VideoPlayer.seekTo(10000)} style={{ marginTop: 10 }} />
    </View>
  );
};

export default App;

关键注意事项

  • 确保React Native与原生模块的包名一致,避免注册失败
  • 播放器资源释放必须在Activity的onDestroy中执行,防止内存泄漏
  • 事件监听在组件卸载时一定要移除,避免内存泄漏
  • 如果需要传递复杂数据,可使用ReadableMap/WritableMap进行序列化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 22:57:26