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

React Native流媒体应用如何禁用AirPlay、屏幕镜像/投屏功能?

React Native 禁用AirPlay、屏幕投屏/镜像方案

iOS 平台实现

  • 禁用AirPlay外部播放:如果使用react-native-video,在播放器配置中设置allowsExternalPlayback={false},阻止视频通过AirPlay输出到外部设备。
    import Video from 'react-native-video';
    
    <Video
      source={{ uri: 'your-video-url' }}
      allowsExternalPlayback={false}
      // 其他播放配置项
    />
    
  • 监听外接屏幕连接(拦截屏幕镜像):通过原生iOS代码监听UIScreenDidConnectNotification,检测到外接屏幕时暂停播放或弹出版权提示。可创建原生模块实现:
    // RNDisableScreenMirror.m
    #import <React/RCTBridgeModule.h>
    #import <React/RCTEventEmitter.h>
    
    @interface RNDisableScreenMirror : RCTEventEmitter <RCTBridgeModule>
    @end
    
    @implementation RNDisableScreenMirror
    
    RCT_EXPORT_MODULE();
    
    - (NSArray<NSString *> *)supportedEvents {
      return @[@"screenConnected"];
    }
    
    - (void)startObserving {
      [[NSNotificationCenter defaultCenter] addObserver:self
                                               selector:@selector(screenConnected:)
                                                   name:UIScreenDidConnectNotification
                                                 object:nil];
    }
    
    - (void)stopObserving {
      [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    - (void)screenConnected:(NSNotification *)notification {
      [self sendEventWithName:@"screenConnected" body:nil];
    }
    
    @end
    
    在RN层监听事件并处理:
    import { NativeEventEmitter, NativeModules } from 'react-native';
    const { RNDisableScreenMirror } = NativeModules;
    const screenMirrorEmitter = new NativeEventEmitter(RNDisableScreenMirror);
    
    useEffect(() => {
      const subscription = screenMirrorEmitter.addListener('screenConnected', () => {
        videoRef.current?.pause();
        // 显示版权限制提示
      });
      return () => subscription.remove();
    }, []);
    
  • 隐藏系统AirPlay控件:确保应用内不提供AirPlay选择入口,避免用户主动触发投屏。

Android 平台实现

  • 拦截Google Cast投屏:若使用react-native-video,可配置disableCast={true}(部分版本支持);或通过原生代码监听MediaRouter路由选择:
    // MainActivity.java
    import android.media.MediaRouter;
    import android.os.Bundle;
    import com.facebook.react.ReactActivity;
    import com.facebook.react.modules.core.DeviceEventManagerModule;
    
    public class MainActivity extends ReactActivity {
      private MediaRouter mediaRouter;
      private MediaRouter.Callback mediaRouterCallback;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mediaRouter = (MediaRouter) getSystemService(MEDIA_ROUTER_SERVICE);
        mediaRouterCallback = new MediaRouter.Callback() {
          @Override
          public void onRouteSelected(MediaRouter router, int type, MediaRouter.RouteInfo info) {
            sendEventToRN("castDetected");
          }
        };
      }
    
      @Override
      protected void onResume() {
        super.onResume();
        mediaRouter.addCallback(MediaRouter.ROUTE_TYPE_LIVE_VIDEO, mediaRouterCallback);
      }
    
      @Override
      protected void onPause() {
        super.onPause();
        mediaRouter.removeCallback(mediaRouterCallback);
      }
    
      private void sendEventToRN(String eventName) {
        getReactInstanceManager().getCurrentReactContext()
          .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
          .emit(eventName, null);
      }
    }
    
    RN层监听事件:
    import { DeviceEventEmitter } from 'react-native';
    
    useEffect(() => {
      const subscription = DeviceEventEmitter.addListener('castDetected', () => {
        videoRef.current?.pause();
        // 显示版权提示
      });
      return () => subscription.remove();
    }, []);
    
  • 拦截MediaProjection投屏(Android 10+):监听系统投屏启动广播,检测到投屏时中断播放:
    // 广播接收器类
    public class ScreenCaptureReceiver extends BroadcastReceiver {
      @Override
      public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_MEDIA_PROJECTION_START.equals(intent.getAction())) {
          ((MainActivity)context).sendEventToRN("screenCaptureStarted");
        }
      }
    }
    
    // 在MainActivity中注册广播
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_PROJECTION_START);
      registerReceiver(new ScreenCaptureReceiver(), filter);
    }
    
  • Manifest配置增强:在AndroidManifest.xml中添加限制,减少被捕获的可能:
    <application
      android:allowAudioPlaybackCapture="false"
      android:allowBackup="false">
      <!-- 其他配置 -->
    </application>
    

注意事项

  • 完全屏蔽系统级投屏(如iOS原生屏幕镜像)存在局限性,部分系统功能无法通过应用完全禁用,但上述方案可最大程度阻止用户通过应用触发投屏,或在投屏发生时立即中断播放。
  • 需覆盖多版本iOS/Android设备测试,确保功能兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 09:06:37