如何使video标签可以支持播放flv,fmp4,WebRTC三种格式

在H5中新增的video标签使得我们可以直接在浏览器中播放视频,但有些视频格式却不支持直接利用video的src属性进行播放,比如上述三种格式中的flv和webrtc格式。要使 HTML 的 <video> 标签支持播放 FLV 和 WebRTC 格式的视频,我们需要使用一些额外的技术和库,下面是三种播放格式配合video标签的具体实现代码,由于我目前使用的框架为react,所以下面代码实现均为React + TS。

  1. 播放 FLV 格式:

    • 使用 JavaScript 库,如 flv.js,它允许在不支持 Flash 的浏览器中播放 FLV 视频。
    • <video> 标签与 flv.js 结合使用,该库可以接收 FLV 流并通过 Media Source Extensions (MSE) API 在浏览器中播放。
import 复制代码
import flv from 'flv.js';

const FLVPlayer = ({ url }) => {
    const videoRef = useRef(null);

    useEffect(() => {
        if (flv.isSupported()) {
            const flvPlayer = flv.createPlayer({
                type: 'flv',
                url: url
            });
            flvPlayer.attachMediaElement(videoRef.current);
            flvPlayer.load();

            return () => {
                flvPlayer.destroy();
            };
        }
    }, [url]);

    return <video ref={videoRef} controls style={{ width: '100%' }} />;
};

export default FLVPlayer;
  1. 播放 FMP4 (Fragmented MP4) 格式:

    • FMP4 通常与 Adaptive Streaming 如 HLS 或 DASH 结合使用。
    • 可以使用如 hls.jsdash.js 等库来播放这种格式的视频。
    • 这些库使用 MSE API 在浏览器中播放分段的 MP4 文件。

示例基于hls.js实现

import 复制代码
import Hls from 'hls.js';

const FMP4Player = ({ url }) => {
    const videoRef = useRef(null);

    useEffect(() => {
        const hls = new Hls();
        hls.loadSource(url);
        hls.attachMedia(videoRef.current);

        return () => {
            hls.destroy();
        };
    }, [url]);

    return <video ref={videoRef} controls style={{ width: '100%' }} />;
};

export default FMP4Player;
  1. 播放 WebRTC 格式:

WebRTC 的实现更加复杂,因为它涉及到实时通信。想做到通过webrtc实现视频的播放,首先需要服务端部署信令服务,按照客户端通过 RTCPeerConnection 实例的 createOffer 方法生成媒体描述并监听 track 事件,将生成的客户端媒体描述给到服务端去换取服务端生成的媒体描述,然后将换取后的服务端生成的媒体描述给到 客户端的RTCPeerConnection 会自动触发 track事件,在触发的 track 事件中可以获取媒体流,此时将媒体流给到 video 的 srcObject 属性就可以通过 webRtc 实现视频播放。

下面示例是基于已经获取到媒体流的情况下去实现的,具体如何获取媒体流较为复杂,后面会出一起详细的讲解如何获取。

import 复制代码
const WebRTCPlayer = ({ stream }) => {
    const videoRef = useRef(null);

    useEffect(() => {
        if (videoRef.current) {
            videoRef.current.srcObject = stream;
        }
    }, [stream]);

    return <video ref={videoRef} autoPlay controls style={{ width: '100%' }} />;
};

export default WebRTCPlayer;

上面我们已经将三种视频格式分别进行实现,下面我们只需要将上面三种格式都整合到一个组件中去进行使用,并且用type字段来判断当前具体需要使用哪种播放格式来进行对应的处理就好。

import 复制代码
import flv from 'flv.js'; 
import Hls from 'hls.js'; 

// 定义组件的 props 类型
type Props = {
  url: string; 
  type: 'flv' | 'fmp4' | 'webrtc'; 
  stream?: MediaStream; // WebRTC 的媒体流(仅当类型为 webrtc 时使用)
};

const VideoPlayer: React.FC<Props> = ({ url, type, stream }) => {
  const videoRef = useRef<HTMLVideoElement>(null); // 使用 useRef 创建对 video 元素的引用

  useEffect(() => {
    let player; // 用于存储播放器实例

    // 根据视频类型来初始化不同的播放器
    if (type === 'flv' && flv.isSupported()) {
      // 对于 FLV 格式,使用 flv.js
      player = flv.createPlayer({
        type: 'flv',
        url: url,
      });
      player.attachMediaElement(videoRef.current!); // 将视频元素绑定到播放器
      player.load(); // 加载视频
    } else if (type === 'fmp4' && Hls.isSupported()) {
      // 对于 FMP4 格式,使用 hls.js
      player = new Hls();
      player.loadSource(url); // 加载视频源
      player.attachMedia(videoRef.current!); // 将视频元素绑定到播放器
    } else if (type === 'webrtc' && stream) {
      // 对于 WebRTC,直接将 MediaStream 绑定到 video 元素
      videoRef.current!.srcObject = stream;
    }

    // 组件卸载时销毁播放器
    return () => {
      if (player) {
        player.destroy();
      }
    };
  }, [url, type, stream]); 

  
  return <video ref={videoRef} controls autoPlay style={{ width: '100%' }} />;
};

export default VideoPlayer;

使用方法

在其他组件中使用 VideoPlayer 组件时,您需要根据视频类型传入相应的 urlstream。例如:

import 复制代码
// FLV 示例
<VideoPlayer url="path/to/your.flv" type="flv" />

// FMP4 示例
<VideoPlayer url="path/to/your.m3u8" type="fmp4" />

// WebRTC 示例
// 假设 `webrtcStream` 是一个 MediaStream 对象
<VideoPlayer type="webrtc" stream={webrtcStream} />

但要注意的是,这个组件是基于我们已经有了 WebRTC 的 MediaStream 对象来实现的,如果没有获取到WebRTC 的 MediaStream对象,当前组件是无法直接播放WebRTC格式的。

相关推荐
亚里士多没有德7752 分钟前
强制删除了windows自带的edge浏览器,重装不了怎么办【已解决】
前端·edge
micro2010145 分钟前
Microsoft Edge 离线安装包制作或获取方法和下载地址分享
前端·edge
.生产的驴10 分钟前
Electron Vue框架环境搭建 Vue3环境搭建
java·前端·vue.js·spring boot·后端·electron·ecmascript
awonw13 分钟前
[前端][easyui]easyui select 默认值
前端·javascript·easyui
九圣残炎33 分钟前
【Vue】vue-admin-template项目搭建
前端·vue.js·arcgis
柏箱1 小时前
使用JavaScript写一个网页端的四则运算器
前端·javascript·css
TU^1 小时前
C语言习题~day16
c语言·前端·算法
学习使我快乐014 小时前
JS进阶 3——深入面向对象、原型
开发语言·前端·javascript
bobostudio19954 小时前
TypeScript 设计模式之【策略模式】
前端·javascript·设计模式·typescript·策略模式