React 项目中如何使用 easyPlayer-pro.js

news2024/11/16 8:20:22

目录

    • 背景
    • EasyPlayer.js H5播放器简单介绍
      • EasyPlayer.js 简介
      • EasyPlayer.js 功能说明:
      • 配置属性
      • 事件回调
      • 方法
    • 下载 EasyPlayer.js
    • 引入使用
    • 重写webpack
    • 问题处理
    • 证清白
    • 最后

背景

项目中要使用 easyplayer-pro.js 播放视频,查了下资料,网上基本都是 在 Vue 项目中的使用,很少有在 React 项目中使用,即使找到一篇在 React 项目中使用的记录,那也是牛头不对马嘴,前面写的是 React ,后面就是 Vue 的写法,这不扯淡嘛。

所以在经过一番努力学习验证后,写上一篇日记来记录一下,便于自己也方便大家。

EasyPlayer.js H5播放器简单介绍

不愿意看这部分的可以跳过,直接从 【下载 EasyPlayer.js】 查看。

EasyPlayer.js 简介

EasyPlayer.js H5播放器,是一款能够同时支持HTTP、HTTP-FLV、HLS(m3u8)、WS、WEBRTC、FMP4视频直播与视频点播等多种协议,支持H.264、H.265、AAC等多种音视频编码格式,支持MSE、WASM、WebCodec等多种解码方式,支持Windows、Linux、Android、iOS全平台终端的H5播放器,使用简单, 功能强大。

EasyPlayer.js 功能说明:

  • 支持 MSE H264和H265硬解码;
  • 支持 WebCodec H264和H265硬解码;
  • 支持 WASM H264和H265硬解码/软解码;
  • 支持 m3u8/HLS (H265/H265)播放;
  • 支持 Mpeg4格式(H264)播放;
  • 支持 HTTP-FLV/WS-FLV (H265/H265)播放;
  • 支持 HTTP-FMP4/WS-FMP4 (H265/H265)播放;
  • <支持 WEBRTC(easy支持H264/H265、其他流媒体支持H264)播放;
  • 支持 裸流(H264/H265) 播放;
  • 支持 直播和点播播放;
  • 支持 点播多清晰度播放;
  • 支持 全屏或比例显示;
  • 支持 电子放大;
  • 支持 水印(动态水印、幽灵水印);
  • 支持 显示上一个视频最后一帧;
  • 支持 播放器快照截图;
  • 支持 视频录制(WebM格式(音频+视频)、Mp4格式(视频),Flv格式(音频+视频));
  • 支持 超时、断网重连、异常暂停播放等

额外介绍:这个仅支持 Vue 和 普通引入使用。

配置属性

参数说明类型默认值
container播放器容器--
decoderwasm解码地址String-
isResize是否拉伸Booleantrue
loadingText加载显示的文字String加载中
videoBuffer加载显设置最小缓冲时长,单位秒,播放器会自动消除延迟。示的文字Number1
hasAudio是否解析音频Booleantrue
useMSEMSE模式Booleanfasle
useWCSWCS模式Booleanfasle
useSIMD强制使用wasm模式Booleanfalse
background视频封面图片String-
qualityConfig配置清晰Array[‘普清’, ‘高清’, ‘超清’, ‘4K’, ‘8K’]
defaultStreamQuality默认显示的清晰度,如果不设置,会显示第一个清晰度String-
isNotMute是否渲染音频Booleanfalse
recordType视频录制默认mp4格式Stringmp4,flv
playbackForwardMaxRateDecodeIFrame录像倍数Number-
debug控制台日志打印Boolean false
debugLevel打印日志级别默认warnStringdebug,warn

事件回调

事件名说明
play播放事件
pause暂时事件
videoInfo视频信息
audioInfo音频信息
mute音频
error播放异常
kBps当前网速, 单位KB 每秒1次,
recordEnd录制结束的事件
recordStart录制开始的事件
fullscreen当前是否全屏
streamQualityChange清晰度回调
playbackSeek录像时间轴跳转回调
playbackPreRateChange录像倍数的回调
currentPts监听当前渲染帧的时间戳(流里面的)

方法

方法名说明参数
play播放‘url’
playback播放录像
pause暂停播放
isPause返回是否暂停中状态
setBufferTime设置最大缓冲时长 1
setVolume设置音量
getVolume获取音量
exitFullscreen退出全屏
mute静音
cancelMute取消静音
isMute返回是否静音
screenshot获取快照
setFullscreen全屏(取消全屏)播放视频
setStreamQuality设置分辨率必须是qualityConfig里面的数据
forward设置录像倍数
setPlaybackStartTime设置录像跳转时间/s
getVideoInfo获取视频信息
getAudioInfo获取音频信息
destroy关闭视频,释放底层资源

在这里插入图片描述

下载 EasyPlayer.js

按照下面的地址去下载下来,简单。

EasyPlayer.js 访问地址

引入使用

  1. 将下载的文件拷贝到 React 项目的 public 目录下

    注意:不能拷贝到其他文件,只能在这里,有兴趣的同学也可以尝试一下其他地址

    在这里插入图片描述

  2. 然后在 index.html 文件中引入 easyplayer-pro.js

    <!DOCTYPE html>
    <html lang="en">
    	<head>
    		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/>
    		<meta charset="utf-8" />
    		<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    		<title>你的爱豆</title>
    	</head>
    
    	<body>
    	
    		<!-- easyplayer-pro.js 文件 -->
    		<script type="text/javascript" src="./js/easyplayer-pro.js"></script>
    		
    		<!-- react 挂载根节点 -->
    		<div id="root"></div>
    	
    	</body>
    	
    	<script>
    		// 将 EasyPlayerPro 挂载到 window 上,便于全局使用
    		window.EasyPlayerPro = EasyPlayerPro;
    	</script>
    </html>
    
    
  3. 将下载的文件再次拷贝一份到需要使用的组件下

    在这里插入图片描述

  4. 创建视频播放组件,并在组件中添加播放内容

import React, { useEffect, useImperativeHandle, useRef } from "react";
import { Button, Icon, Modal } from "antd";
import { useState } from "react";

// 根据自己的需要定义样式
import './index.less';

// 调用接口
import { getVideoManagerPlay } from "server/video.api";

const _myWindow:any = window;

const EasyPlayerVideoDialog = ({onRef}:any) => {

    const easyPlayerRef:any = useRef(null);

    const [open, setOpen] = useState<boolean>(false);
    const [videoUrl, setVideoUrl] = useState<string>('');
    

    useImperativeHandle(onRef, () => ({
        showModal: (record:any) => {
            
            const {deviceId} = record;
            getVideoUrlFn(deviceId);
            
            setOpen(true);
        }
    }));


    // 获取播放视频地址
    const getVideoUrlFn = async (deviceId:string|undefined) => {
        if (!deviceId) return;
        
        try {
            const params = {
                deviceId,
            };
            const res = await getVideoManagerPlay(params);
            const {code, data}:any = res;
            if (code === 200 && data && typeof data === 'string' && data.length > 0) {
                setVideoUrl(data);
            } else {
                setVideoUrl(''); 
            }
            
        } catch (error) {
            setVideoUrl('');
        }
    };


    useEffect(() => {
        if (!videoUrl) return;
        playCreate();
    }, [videoUrl])


    const playCreate = () => {

        const EasyPlayerPro = _myWindow?.['EasyPlayerPro'];

        if (EasyPlayerPro) {

			// 可以根据自己的需要自行配置
            const easyplayer = new EasyPlayerPro({
                container: document.getElementById('player_box1'),
				
				// 这里需要注意,根据自己打包需求设定
                decoder: process.env.NODE_ENV === 'development' ? './js/decoder-pro.js' : './static/js/easyPlayerPro/decoder-pro.js',  // wasm解码地址
                videoBuffer: 2, // 加载显设置最小缓冲时长,单位秒,播放器会自动消除延迟。
                isResize: false, // 是否拉伸
                text: "",
                loadingText: "加载中",
                // debug: true,
                // debugLevel: 'debug',
                useMSE: true, // MSE模式
                useWCS: true, // WCS模式
                isMulti: true,
                useSIMD: false, // 强制使用wasm模式
                hasAudio: true, // 是否解析音频
                showBandwidth: false, // 显示网速
                showPerformance: false,
                operateBtns: {
                    fullscreen: true,
                    screenshot: true,
                    play: true,
                    audio: true,
                    record: true,
                    quality: true,
                    performance: true,
                },
                watermarkConfig: {
                text: {
                    content: ''
                },
                right: 10,
                top: 10
                },
                playbackForwardMaxRateDecodeIFrame: 1,
                isWebrtcForOthers:true,
                demuxUseWorker: true,
                supportHls265:true,
            });

			// 一些监听事件
            easyplayer.on("fullscreen", function (flag:any) {
                console.log('is fullscreen', flag)
            })

            easyplayer.on('playbackPreRateChange', (rate:any) => {
                easyplayer.forward(rate);
            })

            easyplayer.on('playbackSeek', (data:any) => {
                easyplayer.setPlaybackStartTime(data.ts);
            })

            if (easyPlayerRef.current) easyPlayerRef.current = null;
            easyPlayerRef.current = easyplayer;

            // 开启自动播放
            easyplayer.play(videoUrl);
        }
    }

	// 隐藏弹框重置数据
    const onCancelFn = () => {
        easyPlayerRef.current?.pause();
        easyPlayerRef.current?.destroy();
        easyPlayerRef.current = null;
        setVideoUrl('');
        setOpen(false);
    };

    return (
        <Modal
            className="easyPlayerModal"
            // title="视频监控"
            getContainer={false}
            visible={open}
            footer={null}
            width={1200}
            centered={true}
            maskClosable={true}
            onCancel={onCancelFn}
        >
            <div className="easy-player-wrp">
                <div className="easy-player-box" id="player_box1"/>
            </div>

        </Modal>
    )
};

export default EasyPlayerVideoDialog;

重写webpack

因为我项目中使用 customize-cra 插件,根据插件要求,在项目根目录创建 config-overrides.js 文件重写 webpack 配置。

点击此处可以查看 customize-cra 插件 的所有api及相关解释。

// 引入插件 customize-cra
const {
  override,
  fixBabelImports,
  addLessLoader,
  addWebpackPlugin,
  addWebpackAlias,
  disableEsLint,
  setWebpackOptimizationSplitChunks,
  useBabelRc,
  addBundleVisualizer,
  adjustWorkbox,
  overrideDevServer,
} = require('customize-cra');

// 引入css分离插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

// 下载拷贝文件插件
const CopyWebpackPlugin = require('copy-webpack-plugin');


// 输出文件配置
const appBuildOutput = () => (config) => {
	// 可以根据环境自定义配置输出文件
	
	switch(process.env.NODE_ENV){
		case 'development':
			break;
		case 'product':
			// 关闭sourceMap
		    config.devtool = false;
			
			// 更改生产模式输出的文件名
		    // main.js 不带hash
		    // 按需引入的文件带有hash
		    config.output = {
		      ...config.output,
		      path: paths.appBuild,
		      filename: 'static/js/[name].js',
		      chunkFilename: 'static/js/[name].[contenthash:8].chunk.js',
		    };
		    
		    config.optimization.runtimeChunk = false;

			// 针对 css 拆包
		    config.plugins.forEach((item, index, self) => {
		      if (item instanceof MiniCssExtractPlugin) {
		        self[index] = new MiniCssExtractPlugin({
		          filename: 'static/css/[name].css',
		          chunkFilename: 'static/css/[name].[contenthash:4].chunk.css',
		          ignoreOrder: true,
		        });
		      }
		    });

			// 拷贝 easyPlayer-pro.js到指定目录
			config.plugins.push(
		      new CopyWebpackPlugin(
		        [
		          {
		            from: 'public/js/*.js', // 指定public目录下js文件夹中的所有.js文件
		            to: 'static/js/easyPlayerPro/[name].[ext]', // 指定目标路径,[name]和[ext]是文件名和扩展名的占位符
		          },
		        ]
		      )
		    );
			break;
		// 其他...
	}
	
}


module.exports = {
  	webpack: override(
		// 其他配置...
		appBuildOutput(),
	),
	devServer: overrideDevServer((config) => {
		return {
			...config
			// 其他配置...
		}
	})
}

到这里就结束了吗,就能够正常运行了吗,不一定,请接着往下看。

在这里插入图片描述

问题处理

将打包好的文件放到线上测试环境部署,一运行就报如下错误,这是个啥呀,点击进去一看,都到人家的插件里面去了,那铁定不能去改啊,对吧,那就是我们自身的代码出了问题,继续排查排查。

在这里插入图片描述

经过不断地努力排除,最终定位到 easyPlayer-pro.js 解码视频还需要一个二进制的文件,这个文件没有拷贝进去,所以继续如下操作即可。

经过查找,缺失的这个二进制文件就是以 *.wasm 结尾的文件,问题找到了,那么只要将这个文件在打包的时候拷贝进去就好,所以继续修改我们的 config-overrides.js 文件。
在这里插入图片描述

// 其他...

// 拷贝 easyPlayer-pro.js到指定目录
config.plugins.push(
	new CopyWebpackPlugin(
		[
			// ********** 原来的 **********
			{
				from: 'public/js/*.js', // 指定public目录下js文件夹中的所有.js文件
				to: 'static/js/easyPlayerPro/[name].[ext]', // 指定目标路径,[name]和[ext]是文件名和扩展名的占位符
			},
			
			// ********** 重要 **********
			// 新增:一定要拷贝这里的 *.wasm 格式的文件,否则播放视频一定报错
			{
				from: 'public/js/*.wasm', // 指定public目录下js文件夹中的所有.wasm文件
				to: 'static/js/easyPlayerPro/[name].[ext]', // 指定目标路径,[name]和[ext]是文件名和扩展名的占位符
			}
		]
	)
);

// 其他...

证清白

在这里插入图片描述

因项目保密,就只展示这么一部分。

最后

关于在 React 项目中引用 EasyPlayer.js 到这里就结束了,希望能够对有需要的朋友一些帮助。

如果这篇文章对你还有点儿作用,麻烦点赞,搜藏,如果有哪里不对,可以评论,私信

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1972212.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Axure在数据可视化原型设计中的革新力量

在数据洪流与信息爆炸的当下&#xff0c;产品设计不再局限于界面的美观与功能的堆砌&#xff0c;而是更多地聚焦于如何高效地呈现与解读数据。Axure RP&#xff0c;作为原型设计领域的璀璨明星&#xff0c;正以其独特的魅力&#xff0c;引领着数据可视化原型设计的新风尚。本文…

【云原生】数据库忘记密码怎么办?

相信很多人都会遇到在虚拟机中忘记数据库密码的情况&#xff0c;想必大家都很苦恼&#xff0c;所以今天给大家来讲讲数据库忘记密码了如何修改密码再登录数据库&#xff01;&#xff01;&#xff01; 1、关闭数据库服务 systemctl stop mariadb 2、执行MySQL 服务器在启动时跳…

【LeetCode】146.LRU页面置换

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

C++ string类(你想要的这里都有)

1. string类概述 C语言中&#xff0c;字符串是以“\0”结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数&#xff0c;但是这些库函数与字符串是分离开的&#xff0c;不太符合OOP的思想&#xff0c;而且底层空间需要用户管理&#…

Javaweb项目|ssm基于web的健身中心管理系统的的设计与实现jsp

收藏点赞不迷路 关注作者有好处 文末获取源码 一、系统展示 二、万字文档展示 基于ssm基于web的健身中心管理系统的的设计与实现jsp 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringSpringMVCMyBatisVue 工具&#xff1a;IDEA/Ecilpse、Navicat、…

HTTP常见的请求方法、响应状态码、接口规范介绍

常见的请求方法 GET&#xff08;查询&#xff0c;从服务器获取资源&#xff09;POST&#xff08;新增&#xff0c;在服务器创建资源&#xff09;PUT&#xff08;修改&#xff0c;在服务器更新资源&#xff09;DELETE&#xff08;删除&#xff0c;从服务器删除资源&#xff09;…

跟《经济学人》学英文:2024年07月27日这期 AI firms will soon exhaust most of the internet’s data

AI firms will soon exhaust most of the internet’s data Can they create more? 原文&#xff1a; In 2006 fei-fei li, then at the University of Illinois, now at Stanford University, saw how mining the internet might help to transform AI research. Linguis…

商场购物中心营销怎么玩?附230个参考案例

随着消费市场的不断演变&#xff0c;商场购物中心正面临着前所未有的竞争压力。如何在众多竞争对手中脱颖而出&#xff0c;吸引消费者的目光&#xff1f; 今天道叔将探讨商场购物中心营销的新玩法&#xff0c;帮助您在激烈的市场竞争中占据一席之地。 码字不易&#xff0c;如…

第三方库认识- Mysql 数据库 API 认识

文章目录 一、msyql数据库API接口1.初始化mysql_init()——mysql_init2.链接数据库mysql_real_connect——mysql_real_connect3.设置当前客户端的字符集——mysql_set_character_set4.选择操作的数据库——mysql_select_db5.执行sql语句——mysql_query6.保存查询结果到本地——…

配置frp实现内网穿透(.toml配置文件)

简介 frp 是一款高性能的反向代理应用&#xff0c;专注于内网穿透。它支持多种协议&#xff0c;包括 TCP、UDP、HTTP、HTTPS 等&#xff0c;并且具备 P2P 通信功能。使用 frp&#xff0c;您可以安全、便捷地将内网服务暴露到公网&#xff0c;通过拥有公网 IP 的节点进行中转。…

软件测试---禅道

一、禅道简介 二、安装 三、新手引导 &#xff08;1&#xff09;在系统创建一个新的用户帐号&#xff1a; &#xff08;2&#xff09;在系统创建一个新的项目集&#xff1a; &#xff08;3&#xff09;在系统创建一个新的产品&#xff1a; &#xff08;4&#xff09;在系统创…

【AI学习】[2024北京智源大会]具身智能:面向通用机器人的具身多模态大模型系统

面向通用机器人的具身多模态大模型系统 王 鹤 | 北京大学助理教授&#xff0c;智源学者 边听边做一些记录 一、通用机器人的概念和发展趋势&#xff0c;以及实现通用机器人的基石层、大脑和小脑模型等方面的思考和探索。 主要观点&#xff1a;人形机器人&#xff0c;是未来…

基于SpringBoot+Vue的校园便利平台(带1w+文档)

基于SpringBootVue的校园便利平台(带1w文档) 基于SpringBootVue的校园便利平台(带1w文档) 本平台采用B/S架构、采用的数据库是MySQL&#xff0c;使用JAVA技术开发。该平台的开发方式无论在国内还是国外都比较常见&#xff0c;而且开发完成后使用普遍&#xff0c;可以给平台用户…

多址技术(FDMA,TDMA,CDMA,帧,时隙)(通俗易懂)

多址技术是一种区分用户的技术。 举个例子&#xff0c;一个基站发出信息&#xff0c;如何确定是发给谁的&#xff1f; 这个技术就是解决这个问题的。 多址技术常见的有三种&#xff1a; 频分多址&#xff08;FDMA&#xff09;、时分多址&#xff08;TDMA&#xff09;、码分…

程序员学长 | 快速学习一个算法,UNet

本文来源公众号“程序员学长”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;快速学习一个算法&#xff0c;UNet 今天给大家分享一个超强的算法模型&#xff0c;UNet UNet 是一种卷积神经网络架构&#xff0c;最初由 Olaf Ronne…

快速排序(下)

快速排序&#xff08;下&#xff09; 前言 在上一篇文章中我们了解了快速排序算法&#xff0c;但那是Hoare的版本&#xff0c;其实还有别的版本&#xff1a;一种是挖坑法&#xff0c;它们的区别主要在于如何找基准值。霍尔的版本思路难理解但代码好理解&#xff0c;挖坑法则是…

Java新特性(二) Stream与Optional详解

Java8新特性&#xff08;二&#xff09; Stream与Optional详解 一. Stream流 1. Stream概述 1.1 基本概念 Stream&#xff08;java.util.stream&#xff09; 是Java 8中新增的一种抽象流式接口&#xff0c;主要用于配合Lambda表达式提高批量数据的计算和处理效率。Stream不是…

【前端】中后台框架 添加其他布局的探索

文章目录 前言需求整理第一步&#xff1a;实现可切换布局第二步&#xff1a;配置页面顶部的路由&#xff08;一级路由&#xff09;第三部&#xff1a;配置左侧二级和二级以上的路由第四部&#xff1a;给侧边栏加一个动画第五部&#xff1a;刷新页面之后顶部路由、左侧路由的回显…

5款免费写作生成软件,自动生成原创文章很简单

在人工智能时代的今天&#xff0c;创作者面对写作不再是一件令人望而生畏的事情。随着AI技术的不断发展&#xff0c;涌现出了许多优秀的免费写作生成软件&#xff0c;让自动生成原创文章变得轻松简单。以下为大家详细介绍5款备受赞誉的免费写作生成软件&#xff0c;下面跟随小编…

硬盘数据丢失不再怕,四大恢复工具帮你轻松逆转局面!

硬盘故障、误删文件、病毒攻击等原因导致数据丢失的情况时有发生。面对这种情况&#xff0c;如何高效、快速地进行硬盘数据恢复呢&#xff1f;接下来几款好用的数据恢复软件推荐给大家。 一、福昕数据恢复&#xff1a;全方位恢复&#xff0c;让数据无遗漏 链接&#xff1a;ww…