在H5中新增的video
标签使得我们可以直接在浏览器中播放视频,但有些视频格式却不支持直接利用video
的src属性进行播放,比如上述三种格式中的flv和webrtc格式。要使 HTML 的 <video>
标签支持播放 FLV 和 WebRTC 格式的视频,我们需要使用一些额外的技术和库,下面是三种播放格式配合video
标签的具体实现代码,由于我目前使用的框架为react,所以下面代码实现均为React + TS。
-
播放 FLV 格式:
- 使用 JavaScript 库,如
flv.js
,它允许在不支持 Flash 的浏览器中播放 FLV 视频。 - 将
<video>
标签与flv.js
结合使用,该库可以接收 FLV 流并通过 Media Source Extensions (MSE) API 在浏览器中播放。
- 使用 JavaScript 库,如
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;
-
播放 FMP4 (Fragmented MP4) 格式:
- FMP4 通常与 Adaptive Streaming 如 HLS 或 DASH 结合使用。
- 可以使用如
hls.js
或dash.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;
- 播放 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
组件时,您需要根据视频类型传入相应的 url
或 stream
。例如:
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格式的。