EasyMedia播放rtsp视频流(vue2、vue3皆可用)

news2024/10/6 14:34:31

之前发布过WebRtc播放rtsp视频流的博客,已经解决了web播放rtsp的问题,但WebRtc太耗内存,且需要命令行启动,对用户不太友好,虽然可以写脚本,让用户一键启动。这是无意间发现的另一种web播放rtsp视频流的办法,个人觉得比WebRtc效果更好,且编码更简洁。

1.EasyMedia下载

EasyMedia: Springboot、netty实现的http-flv、websocket-flv直播点播,支持rtsp、h264、h265、rtmp等多种源,h5纯js播放(不依赖flash),不需要nginx等第三方拉流服务 - Gitee.com

2.使用文档

doc/使用教程(简单例子).md · MisterZhang/EasyMedia - Gitee.com

建议使用1.2.0的版本,win、mac运行皆正常。

下载链接:百度网盘 请输入提取码

提取码:kvuj

作者在gitee给出的是1.3的下载链接,win、mac运行皆报错。

启动EasyMedia.jar

浏览器运行:localhost:8888,看到下图说明运行成功,此时可以找一个rtsp视频流做测试。

 

3.前端使用

3.1安装西瓜视频播放插件

package.json中添加依赖

 "xgplayer": "^2.18.2",
 "xgplayer-flv.js": "^2.2.1"

//执行安装命令
npm install

3.2界面中使用

组件

<template>
    <div>
        <div style="height: 100%;width: 100%;display: flex;align-items: center;justify-content: center;">
            <div class="video" v-show="isPlay" :id="elId"></div>
            <div v-show="!isPlay" style="color: #08979C;font-size: 25px;">暂无视频源</div>
        </div>
    </div>
</template>

<script setup lang="ts">
import FlvJsPlayer from 'xgplayer-flv.js';
import Player from 'xgplayer';
import { guid } from '@/utils/util'

const isPlay = ref(false)
const player = ref<any>({})
const elId = guid()

const visibilitychange = onMounted(() => {
    console.log('computed执行');
    document.addEventListener('visibilitychange', function () {
        // console.log(document.visibilityState);
        // console.log(document.hidden);
        if (document.hidden) {
            console.log("页面隐藏")
        }
    });
})

const createPlayer = (url: string, hasCloseBtn: boolean, index: number) => {

    console.log(url);
    console.log(hasCloseBtn);
    console.log(index);

    if (!url) {
        return;
    }

    // if (player) {
    //     changeVideo(url);
    //     return;
    // }

    isPlay.value = true;
    player.value = new FlvJsPlayer({
        id: elId,
        url: url,
        // fitVideoSize: 'auto',
        fluid: true,
        autoplay: true,
        isLive: true,
        playsinline: false,
        screenShot: true,
        whitelist: [''],
        ignores: ['time'],
        closeVideoClick: true,
        // errorTips: '<span class="app-error">无视频源</span>',
        customConfig: {
            isClickPlayBack: false
        },
        flvOptionalConfig: {
            enableWorker: true,
            enableStashBuffer: true, //启用缓存
            stashInitialSize: 4096, //缓存大小4m
            lazyLoad: false,
            lazyLoadMaxDuration: 40 * 60,
            autoCleanupSourceBuffer: true,
            autoCleanupMaxBackwardDuration: 35 * 60,
            autoCleanupMinBackwardDuration: 30 * 60
        } //flv.js可选配置项 [flv.js配置](https://github.com/bilibili/flv.js/blob/master/docs/api.md#config)
    });

    // 自定义播放器按钮
    // let divStr =
    //   '<i class="btn-hover el-icon-camera button-screen-shot" style="font-size: 23px;margin-right: 10px;pointer-events: auto;"></i>' +
    //   '<i class="btn-hover el-icon-s-tools button-set" style="font-size: 23px;margin-right: 10px;pointer-events: auto;"></i>' +
    //   '<i class="btn-hover el-icon-video-camera-solid button-history" style="font-size: 23px;margin-right: 10px;pointer-events: auto;"></i>';

    let divStr = '<i class="btn-hover el-icon-d-arrow-left button-playback" style="font-size: 23px;pointer-events: auto;"></i>';

    let divClose = '<i @click="closePlayer" class="btn-hover el-icon-close app-close-btn-c"></i>';

    let util = Player.util;
    // let customBtn = util.createDom('div', divStr, {}, 'flex align-center justify-center app-player-button'); //'div', divStr, {}, 'class'
    let customBtn = util.createDom(
        'div',
        divStr,
        { style: 'width: 40px;heigth:40px;position: absolute;right: 155px;top: 7px;' },
        'flex align-center justify-center app-player-button'
    ); //'div', divStr, {}, 'class'
    let closeBtn = util.createDom('div', divClose, {}, 'app-close-btn');
    let xgControls = player.root.querySelector('xg-controls');
    let xgError = player.root.querySelector('xg-error');
    xgControls.appendChild(customBtn);
    player.root.appendChild(closeBtn);

    // let shot = customBtn.querySelector('.button-screen-shot');
    // let set = customBtn.querySelector('.button-set');
    // let history = customBtn.querySelector('.button-history');
    let closeBtnc = closeBtn.querySelector('.app-close-btn-c');
    let playback = customBtn.querySelector('.button-playback');

    player.on('play', () => { });
    player.on('focus', () => {
        if (hasCloseBtn) {
            closeBtn.style.display = 'block';
        }
    });
    player.on('ended', () => { });
    player.on('blur', () => {
        closeBtn.style.display = 'none';
    });

    player.on('error', () => { });

    if (closeBtnc) {
        closeBtnc.addEventListener('click', () => {
            closePlayer();
        });
    }

    // 点击视频时间,设置selectIndex
    // player.video.addEventListener('click', () => {
    //     $emit('clickPlayer', index);
    // });
}

const changeVideo = (url: string) => {
    player.src = url;
}

const closePlayer = () => {
    isPlay.value = false;
    if (player) {
        player.value.destroy();
    }
}

const playObjDestroy = () => {
    if (player) {
        player.value.destroy();
    }
    console.log('销毁了');
}

defineExpose({
    createPlayer,
    playObjDestroy
})


</script>

使用

//template
<rtsp-player ref="rtspPlayerRef"></rtsp-player>

//script  (vue3+vite)
import RtspPlayer from '@/components/rtspPlayer/index.vue';
const rtspPlayerRef = shallowRef<InstanceType<typeof RtspPlayer>>()

//启动播放rtsp组件方法。ws://eastMedia运行的设备的ip地址:8866/live?url=rtsp:xxx/yyy/zzz
rtspPlayerRef.value?.createPlayer('ws:/localhost:8866/live?url=rtsp:xxx/yyy/zzz', true, 0);

//销毁rtsp组件方法
rtspPlayerRef.value?.playObjDestroy()

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

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

相关文章

相当Python程序员,选择培训班还是自学?我结合自己的经历谈谈看法

前几天我写了一篇文章&#xff0c;分享了自己当上程序员的经历。然后&#xff0c;我收到了很多小伙伴的提问&#xff0c;都在问同一个问题&#xff0c;即如何选择报培训班还是自学。今天&#xff0c;我结合自己的个人经历&#xff0c;来谈一下个人的看法。 我认为这个问题的第…

C/C++内存管理以及new/delete的底层实现。

一、C/C 内存分布 我们平常写代码所用的内存叫虚拟内存&#xff0c;是操作系统分配给每个进程的4G的内存&#xff0c;其中3G叫用户空间&#xff0c;1G叫内核空间。 我们所用的也就是3G的用户空间&#xff0c;如下图&#xff1a; 说明&#xff1a; 1. 代码段—可执行的代码/只…

【Linux】Linux学习之常用命令一

介绍 这里是小编成长之路的历程&#xff0c;也是小编的学习之路。希望和各位大佬们一起成长&#xff01; 以下为小编最喜欢的两句话&#xff1a; 要有最朴素的生活和最遥远的梦想&#xff0c;即使明天天寒地冻&#xff0c;山高水远&#xff0c;路远马亡。 一个人为什么要努力&a…

【嵌入式笔/面试】嵌入式软件基础题和真题总结——单片机与Linux

在学习的时候找到几个十分好的工程和个人博客&#xff0c;先码一下&#xff0c;内容都摘自其中&#xff0c;有些重难点做了补充&#xff01; 才鲸 / 嵌入式软件笔试题汇总 嵌入式与Linux那些事 阿秀的学习笔记 小林coding 百问网linux 嵌入式软件面试合集 2022年春招实习十四面…

在离职1年后,我后悔了,决定再战阿里,涨薪50%,成为卷王

2021年初&#xff0c;我通过一整天的笔试及面试加入一家&#xff08;某一线城市国资委全资控股&#xff09;某集团的研究机构&#xff08;中央研究院&#xff09;&#xff0c;任职中级软件测试工程师&#xff1b;在这边工作了整整一年&#xff0c;目前已经跳槽到一家互联网公司…

Linux之系统j基本设置(四)

1、Linux 系统基本设置 1、系统时间管理 查看系统当前时间和时区 [root192 ~]# date 2023年 05月 04日 星期四 22:43:16 EDT [root192 ~]# date -R Thu, 04 May 2023 22:43:24 -0400 [root192 ~]# date %Y %m %d %H:%M:%S 2023 05 04 22:43:38设置完整时间 [root192 ~]# da…

智能安防系统-视频监控系统

一、智能安防系统 1、智能安防系统介绍 安全防范系统成为了智慧城市与物联网行业应用中的一个非常重要的子系统。 安防系统主要包括&#xff1a;视频监控系统、入侵报警系统、出入口控制系统、电子巡查系统以及智能停车场管理系统等5个子系统。 AI人工智能安防系统功能&#xf…

第三十四章 Unity人形动画(上)

在我们DirectX课程中&#xff0c;我们讲过一个模型最少拥有网格和材质&#xff0c;可以没有动画。游戏场景中的静态物体就可以是这样的模型&#xff0c;例如花草树木&#xff0c;建筑物等等&#xff0c;他们通过MeshRenderer就可以渲染。对于一个带有动画的FBX文件&#xff0c;…

爬虫实验笔记

这里的爬虫实验害暂时没有遇到验证码等问题&#xff0c;步骤可以简单概括为&#xff1a; 1.找到爬虫必要的信息&#xff1b; 2.内容提取&#xff1b; 3.将提取到的内容保存至xlsx文件 1.找到爬虫必要的信息 以zh为例&#xff0c;首先找一个自己感兴趣的贴&#xff0c;进入开…

webp格式转换成jpg,webp转jpg方法步骤

webp格式转换成jpg&#xff0c;webp转jpg方法步骤。办公室工作集科学性、规范性于一体&#xff0c;仅凭过去的一些经验和习惯&#xff0c;很难提升工作的质量和水平。因此&#xff0c;作为办公室工作人员来说&#xff0c;必须要以科学的理念&#xff0c;运用现代办公管理软件来…

PSP - D-I-TASSER DeepMSA2 源码简读

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/130519945 DIT&#xff1a;https://zhanggroup.org/D-I-TASSER/ D-I-TASSER (Deep-learning based Iterative Threading ASSEmbly Refin…

MySQL学习笔记第八天

第07章单行函数 4. 日期和时间函数 4.6 计算日期和时间的函数 第1组&#xff1a; 函数用法DATE_ADD(datetime,lNTERVAL exprtype)&#xff0c;ADDDATE(date,INTERVAL exprtype)返回与给定日期时间相差INTERVAL时间段的日期时间DATE_SUB(date,lNTERVAL expr type)&#xff0…

vulnhub dc-5

1.信息搜集 官方文档描述 主要内容不会使用到ssh&#xff0c;进入的方式很难被发现&#xff0c;是改变页面刷新的方法&#xff0c;只有一个flag nmap扫描 存活主机 192.168.85.176 端口 80 111 中间件&#xff1a; nginx 2.访问网站&#xff0c;进行进一步信息搜集 通过这两张…

加速 AI 训练,如何在云上实现灵活的弹性吞吐?

AI 已经成为各行各业软件研发的基础&#xff0c;带来了前所未有的效率和创新。今天&#xff0c;我们将分享苏锐在AWS量化投研行业活动的演讲实录&#xff0c;为大家介绍JuiceFS 在 AI 量化投研领域的应用经验&#xff0c;也希望为其他正在云上构建机器学习平台&#xff0c;面临…

4面美团测试工程师,因为这个小细节,直接让我前功尽弃.....

说一下我面试别人时候的思路 反过来理解&#xff0c;就是面试时候应该注意哪些东西&#xff1b;用加粗部分标注了 一般面试分为这么几个部分&#xff1a; 一、自我介绍 这部分一般人喜欢讲很多&#xff0c;其实没必要。大约5分钟内说清楚自己的职业经历&#xff0c;自己的核…

C++11入门基础知识

文章目录 C11简介列表初始化std::initializer_list 变量类型推导nullptr范围for循环STL中的一些变化 C11简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1)&#xff0c;使得C03这个名字已经取代了C98称为C11之前的最新C标准名称。不过由于C03(TC1)主要是对C98标准中…

阿里云Alibaba Cloud Linux镜像操作系统性能兼容如何?

阿里云服务器操作系统Alibaba Cloud Linux镜像怎么样&#xff1f;可以代替CentOS吗&#xff1f;Alibaba Cloud Linux兼容性如何&#xff1f;有人维护吗&#xff1f;漏洞可以修复吗&#xff1f;Alibaba Cloud Linux完全兼容CentOS&#xff0c;并由阿里云官方免费提供长期维护。 …

【五一创作】自动驾驶技术未来大有可为

本文概要 自动驾驶技术是当今汽车行业的发展热点之一&#xff0c;但其也存在着许多争议。大家也可以从以下几个维度谈谈你对这项技术的看法。 &#x1f31f;&#x1f31f;&#x1f31f;个人简介&#x1f31f;&#x1f31f;&#x1f31f; ☀️大家好&#xff01;我是新人小白博…

4.2 线性表顺序表(上)

目录 目录结构 线性表 线性表的特征&#xff1a; 顺序表存储结构的表示 顺序表存储结构的特点 顺序存储结构的表示 线性表的基本运算 基本运算的相关算法 线性表的基本运算 线性表 目录结构 线性表 线性表是包含若干数据元素的一个线性序列 记为&#xff1a; L(a0, …

Android FlexboxLayout布局

FlexboxLayout 布局 一、简介二、使用三、功能详解FlexboxLayout属性flexWrapflexDirectionalignItemsjustifyContentalignContentdividerDrawableHorizontal、showDividerHorizontaldividerDrawableVertical、showDividerVerticaldividerDrawable、showDividermaxLine Flexbox…