肥仔教程网

SEO 优化与 Web 开发技术学习分享平台

解决在react native中播放ws://格式的视频流

海康威视摄像头提供的 ws:// 或 wss:// 格式的视频流,通常是封装了 FLV (Flash Video) 或其他实时流协议的数据。

标准的 React Native 视频播放器(如 react-native-video)和浏览器 <video> 标签一样,本身不支持直接播放 ws:// 协议的 FLV 实时流。

因此,解决方案的核心在于:在 React Native 中找到一个能够解码 ws:// 协议和 FLV 视频格式的播放器库。

核心问题分析

  1. 协议问题: ws:// (WebSocket) 是一种通信协议,不是像 HTTP 那样的媒体传输协议。视频数据是通过 WebSocket 连接进行传输的。
  2. 编码问题: WebSocket 传输过来的数据通常是 FLV 格式。你需要一个能实时解码 FLV 的播放器。
  3. 平台问题: 解决方案必须能在 React Native (iOS 和 Android) 环境下运行。

解决方案:使用react-native-nodemediaclient

目前在 React Native 生态中,处理此类 ws-flv 视频流最成熟、最推荐的库是
react-native-nodemediaclient。

这个库专门为处理实时流媒体而设计,它底层封装了强大的 NodeMediaClient SDK,可以完美地解决你的问题。

为什么推荐
react-native-nodemediaclient?

  • 原生支持 ws-flv: 它是为数不多的、能直接在原生端(非 WebView)解码 ws:// 协议下 FLV 视频流的库。
  • 高性能: 它使用原生代码进行解码和渲染,性能远超 WebView 方案,可以做到低延迟、高流畅度的播放。
  • 功能丰富: 不仅支持播放(pull stream),还支持推流(push stream),即用手机摄像头进行直播。
  • 跨平台: 同时支持 iOS 和 Android。

集成步骤

下面是集成
react-native-nodemediaclient 的基本步骤:

1. 安装库

npm install react-native-nodemediaclient --save
# 或者
yarn add react-native-nodemediaclient

2. 链接原生模块

对于较新版本的 React Native (0.60+),自动链接通常会生效。你只需要安装 pods 即可。

cd ios && pod install

对于 Android,通常不需要额外步骤,但请确保你的项目配置正确。

3. 配置权限

视频播放和网络访问需要相应的权限。

  • Android (android/app/src/main/AndroidManifest.xml): 确保已声明网络权限。
<uses-permission android:name="android.permission.INTERNET" />

iOS (
ios/YourProject/Info.plist): 通常不需要特殊权限,但如果你需要访问非加密的 ws:// 地址,可能需要配置 App Transport Security。

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

4. 在代码中使用播放器

使用起来非常简单,它提供了一个名为 NodePlayerView 的组件。

import React, { useRef } from 'react';
import { View, Button, StyleSheet } from 'react-native';
import { NodePlayerView } from 'react-native-nodemediaclient';

const HikvisionPlayer = () => {
  // 替换成你的海康摄像头 ws-flv 地址
  const videoStreamUrl = 'ws://your.hikvision.stream.address/path';
  const playerRef = useRef(null);

  return (
    <View style={styles.container}>
      <NodePlayerView
        style={styles.player}
        ref={playerRef}
        inputUrl={videoStreamUrl}
        scaleMode={'ScaleAspectFit'} // 视频缩放模式
        bufferTime={300}             // 缓冲时间 (ms)
        maxBufferTime={1000}         // 最大缓冲时间 (ms)
        autoplay={true}              // 自动播放
        onStatus={(code, msg) => {
          // 监听播放器状态
          // 例如: 2001=连接中, 2002=连接成功, 2004=播放结束
          console.log(`Status: code=${code} msg=${msg}`);
        }}
      />
      <View style={styles.controls}>
        <Button title="停止播放" onPress={() => playerRef.current?.stop()} />
        <Button title="开始播放" onPress={() => playerRef.current?.start()} />
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#000',
  },
  player: {
    flex: 1, // 让播放器占满可用空间
  },
  controls: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    padding: 10,
  },
});

export default HikvisionPlayer;

总结与对比

结论: 对于在 React Native 中播放海康威视提供的 ws:// 视频流的需求,
react-native-nodemediaclient 是目前最直接、最高效的解决方案。




react-native-nodemediaclient
是一个功能强大的流媒体库,主要用于在 React Native 应用中实现直播推流和播放。

下面我将为你全面总结它的用法,涵盖播放器 (NodePlayerView)推流器 (NodeCameraView) 两大核心功能,以及它们的详细属性(Props)、方法(Methods)和事件回调(Events)。


一、核心功能概览


react-native-nodemediaclient
主要提供两个 React 组件:

1.NodePlayerView: 用于播放实时或点播视频流。这是你用来播放海康 ws-flv 视频流的组件。2.NodeCameraView: 用于采集摄像头和麦克风数据,并推送到流媒体服务器。也就是直播推流功能。


二、播放器 NodePlayerView 的用法

这是用于消费(观看)视频流的组件。

1. 主要属性 (Props)

属性名

类型

默认值

描述

inputUrl

string

-

【必需】 视频流的地址。支持 rtmp, http-flv, ws-flv 等格式。例如:
ws://your.server/live/stream。

autoplay

boolean

false

是否在组件加载后自动开始播放。

scaleMode

string

ScaleAspectFit

视频画面的缩放模式。可选值:'ScaleToFill' (拉伸填满), 'ScaleAspectFit' (保持宽高比,黑边填充), 'ScaleAspectFill' (保持宽高比,裁剪填满)。

bufferTime

number

200

播放缓冲时间(毫秒)。较小的值可以降低延迟,但可能增加卡顿风险。

maxBufferTime

number

1000

最大缓冲时间(毫秒)。网络波动时,播放器最多缓存多长时间的数据。

renderType

string

SURFACEVIEW (Android)

【仅Android】 指定渲染视图类型。可选值:'SURFACEVIEW' (性能更好,但不能做形变和动画), 'TEXTUREVIEW' (性能稍差,但支持动画、透明度等)。

audioEnable

boolean

true

是否开启音频播放。

cryptoKey

string

-

如果视频流经过 AES-128 加密,在此处提供解密密钥。

pageEnable

boolean

false

【仅iOS】 是否开启画中画功能 (Picture-in-Picture)。

onStatus

function

-

【重要】 状态变化时的回调函数,onStatus={(code, msg) => {}}。

2. 主要方法 (Methods)

你需要通过 ref 来调用这些方法。

const playerRef = useRef(null);
// <NodePlayerView ref={playerRef} ... />

方法名

参数

描述

start()

-

开始播放。如果 autoplay 为 false,你需要手动调用此方法。

stop()

-

停止播放并断开连接。

pause()

-

暂停播放。注意:对于实时流(直播),暂停后恢复可能会导致画面跳跃到当前直播时间点。

seek(seconds)

number

跳转到指定的播放时间点(秒)。仅对点播(VOD)视频流有效。

3. 状态回调 onStatus

这是监控播放器状态的关键。code 是一个数字,代表不同的事件。

Code

含义

建议操作

1000

正在连接

显示加载动画

1001

连接成功

隐藏加载动画

1002

连接失败

显示重试按钮

1003

连接断开

显示重试按钮

1004

开始播放

-

1005

播放结束

显示重播按钮

1006

网络异常

提示用户检查网络

1102

收到视频尺寸

可以根据返回的 msg (如 "720x1280") 调整播放器宽高比

示例代码:

import React, { useRef } from 'react';
import { View, Button, Text, StyleSheet } from 'react-native';
import { NodePlayerView } from 'react-native-nodemediaclient';


const LivePlayer = ({ streamUrl }) => {
  const playerRef = useRef(null);
  const [statusText, setStatusText] = React.useState('未连接');


  return (
    <View style={styles.container}>
      <NodePlayerView
        style={styles.player}
        ref={playerRef}
        inputUrl={streamUrl}
        scaleMode={'ScaleAspectFit'}
        bufferTime={300}
        autoplay={true}
        onStatus={(code, msg) => {
          console.log(`Status: code=${code} msg=${msg}`);
          // 在这里根据 code 更新 UI
          switch (code) {
            case 1000: setStatusText('连接中...'); break;
            case 1001: setStatusText('连接成功'); break;
            // ... 其他状态
            default: setStatusText(`状态: ${code}`);
          }
        }}
      />
      <Text style={styles.status}>{statusText}</Text>
      <Button title="停止" onPress={() => playerRef.current?.stop()} />
    </View>
  );
};

三、推流器 NodeCameraView 的用法

这是用于采集设备音视频并进行直播推流的组件。

1. 主要属性 (Props)

属性名

类型

默认值

描述

outputUrl

string

-

【必需】 推流地址。通常是 RTMP 格式,例如
rtmp://your.server/live/streamKey。

camera

object

{ cameraId: 0, cameraFrontMirror: true }

摄像头配置。cameraId: 0=后置, 1=前置。cameraFrontMirror: 是否开启前置摄像头镜像。

audio

object

{ bitrate: 32000, profile: 1, samplerate: 44100 }

音频编码配置。bitrate: 码率, profile: 编码规格, samplerate: 采样率。

video

object

{ preset: 12, bitrate: 400000, profile: 1, fps: 15, videoFrontMirror: false }

视频编码配置。preset: 编码预设, bitrate: 码率, profile: 编码规格, fps: 帧率。

autopreview

boolean

true

是否在组件加载后自动开启摄像头预览。

denoise

boolean

false

是否开启音频降噪。

dynamicRateEnable

boolean

false

是否开启动态码率调整。开启后,会根据网络状况自动调整视频码率。

onStatus

function

-

【重要】 推流状态变化的回调函数。

2. 主要方法 (Methods)

同样通过 ref 调用。

方法名

参数

描述

startPreview()

-

开启摄像头预览。

stopPreview()

-

关闭摄像头预览。

start()

-

开始推流。

stop()

-

停止推流。

switchCamera()

-

切换前后摄像头。

flashEnable(enable)

boolean

打开或关闭闪光灯。

3. 状态回调 onStatus

推流的状态码与播放器类似,但含义不同。

Code

含义

2000

正在连接推流服务器

2001

连接成功,开始推流

2002

连接错误

2004

连接断开

2100

网络状况不佳,推流不流畅

2101

网络恢复,推流流畅

示例代码:

import React, { useRef, useState } from 'react';
import { View, Button, StyleSheet } from 'react-native';
import { NodeCameraView } from 'react-native-nodemediaclient';


const LivePublisher = ({ streamUrl }) => {
  const cameraRef = useRef(null);
  const [isPublishing, setIsPublishing] = useState(false);


  const handlePublish = () => {
    if (isPublishing) {
      cameraRef.current?.stop();
      setIsPublishing(false);
    } else {
      cameraRef.current?.start();
      setIsPublishing(true);
    }
  };


  return (
    <View style={styles.container}>
      <NodeCameraView
        style={styles.camera}
        ref={cameraRef}
        outputUrl={streamUrl}
        camera={{ cameraId: 1, cameraFrontMirror: true }}
        audio={{ bitrate: 32000, profile: 1, samplerate: 44100 }}
        video={{ preset: 12, bitrate: 400000, profile: 1, fps: 15, videoFrontMirror: false }}
        autopreview={true}
        onStatus={(code, msg) => {
          console.log(`Publish Status: code=${code} msg=${msg}`);
        }}
      />
      <Button title="切换摄像头" onPress={() => cameraRef.current?.switchCamera()} />
      <Button
        title={isPublishing ? '停止直播' : '开始直播'}
        onPress={handlePublish}
      />
    </View>
  );
};

四、总结

o核心用途:该库是 React Native 中处理 RTMP/FLV 直播流 的首选方案。o播放 ws-flv:使用 NodePlayerView,将海康威视的 ws:// 地址直接传入 inputUrl 即可。通过 onStatus 监控状态,通过 ref 控制播放。o直播推流:使用 NodeCameraView,配置好 outputUrl 和音视频参数,通过 ref 控制推流和摄像头。o关键点

oref 是必须的:所有主动操作(如开始、停止、切换摄像头)都依赖 ref。oonStatus 是核心:所有状态变化(连接、断开、错误)都通过这个回调来获取,是实现健壮播放/推流逻辑的基础。o权限:确保在 Android 和 iOS 上配置了必要的网络和摄像头/麦克风权限。

这份总结涵盖了
react-native-nodemediaclient
的绝大部分常用功能。你可以根据自己的具体需求,查阅这些属性和方法进行开发。


接下来,我们可以:

o深入探讨某个特定属性(如 video 或 audio 的详细配置)如何影响性能和画质。o一起设计一个包含重连、错误提示等功能的更完整的播放器组件。o如果你有推流需求,我们可以讨论如何搭建一个配套的流媒体服务器(如 Node-Media-Server)。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言