vue 3.0 + vite + flv 视频流播放

官方提供的 demo 地址,大家可以用自己的流地址,先试试是否符合需求;

http://bilibili.github.io/flv.js/demo/

Flv.js API

https://gitee.com/mirrors/flv.js/blob/master/docs/api.md

安装 Flv.js

npm install --save flv.js

更改 tsconfig.json 配置项

将 tsconfig.json 配置项 moduleResolution:“bundler” 改为 moduleResolution:“node” ,否则当我们引入 flv.js 或者 vue 会有警告;

在这里插入图片描述

代码

<script setup lang="ts">
import flvjs from 'flv.js'
import { onMounted, ref, onUnmounted } from 'vue'

const flvPlayer: any = ref()

onMounted(() => {
    console.log('isSupported: ' + flvjs.isSupported())
    console.log('是否支持点播视频:' + flvjs.getFeatureList().mseFlvPlayback)
    console.log(
        '是否支持httpflv直播流:' + flvjs.getFeatureList().mseLiveFlvPlayback
    )
    initFlv()
})

/**
 * 创建 flvjs 实例
 */
const initFlv = () => {
    const ele = document.getElementById('video-contianer')
    flvPlayer.value = flvjs.createPlayer({
        type: 'flv', // 指定视频类型
        isLive: true, // 开启直播
        hasAudio: false, // 关闭声音
        cors: true, // 开启跨域访问
        url: 'https://mister-ben.github.io/videojs-flvjs/bbb.flv', // 指定流链接
    })
    // 将flvjs对象和DOM对象绑定
    flvPlayer.value.attachMediaElement(ele)
    play()
    flvEvent()
}

const play = () => {
    flvPlayer.value.load()
    flvPlayer.value.play()
}

// flvjs播放器事件侦听
const flvEvent = () => {
    // 视频错误信息回调
    flvPlayer.value.on(
        flvjs.Events.ERROR,
        (errorType: any, errorDetail: any, errorInfo: any) => {
            console.log(
                '类型:' + JSON.stringify(errorType),
                '报错内容' + errorDetail,
                '报错信息' + errorInfo
            )
        }
    )
    //【重要事件监听】http 请求建立好后,该事件会一直监听 flvjs 实例
    flvPlayer.value.on(
        flvjs.Events.STATISTICS_INFO,
        (errorType: any, errorDetail: any, errorInfo: any) => {
            console.log(
                '类型:' + JSON.stringify(errorType),
                '报错内容' + errorDetail,
                '报错信息' + errorInfo
            )
        }
    )
}

/**
 * 重新加载视频
 */
const load = () => {
    if (flvPlayer.value != null) {
        destory()
    }
    initFlv()
}
/**
 * 播放
 */
const start = () => flvPlayer.value.play()
/**
 * 暂停
 */
const pause = () => flvPlayer.value.pause()
/**
 * 销毁
 */
const destory = () => {
    flvPlayer.value.pause()
    flvPlayer.value.unload()
    flvPlayer.value.detachMediaElement()
    flvPlayer.value.destroy()
    flvPlayer.value = null
}
/**
 * 截图
 */
const screenshot = () => {
    const ele = document.getElementById('video-contianer') as HTMLVideoElement
    const canvas = document.createElement('canvas') as HTMLCanvasElement
    canvas.width = ele.clientWidth
    canvas.height = ele.clientHeight
    const ctx = canvas.getContext('2d') as CanvasRenderingContext2D
    ctx.drawImage(ele, 0, 0, ele.clientWidth, ele.clientHeight)
    viewPicture(canvas.toDataURL('image/jpeg'))
}
/**
 * 截图预览
 */
const viewPicture = (url: string) => {
    const id = 'viewPicture' + new Date().getTime()
    var container = document.createElement('div')
    container.id = id
    container.style.cssText =
        'position: fixed;right:0;bottom:0;height:200px;width:300px;transition: 3s;'
    var img = document.createElement('img')
    img.style.cssText = 'width:100%;height:100%;object-fit: inherit;'
    img.src = url
    container.appendChild(img)
    document.body.appendChild(container)

    setTimeout(() => {
        container.style.width = '0'
        container.style.height = '0'
    }, 3000)
    setTimeout(() => {
        document.body.removeChild(document.getElementById(id) as HTMLElement)
    }, 5000)
}
/**
 * 缩放
 */
const zoom = () => {
    if (!!isFullscreen()) exitFullScreen()
    else requestFullScreen()
}

const isFullscreen = () => {
    const documentScreenElement = document as Document & {
        mozFullScreenElement(): Promise<void>
        webkitFullscreenElement(): Promise<void>
        msFullscreenElement(): Promise<void>
    }
    return (
        documentScreenElement.fullscreenElement ||
        documentScreenElement.msFullscreenElement ||
        documentScreenElement.mozFullScreenElement ||
        documentScreenElement.webkitFullscreenElement ||
        false
    )
    // return (
    //     document.fullscreenElement ||
    //     document.msFullscreenElement ||
    //     document.mozFullScreenElement ||
    //     document.webkitFullscreenElement ||
    //     false
    // )
}
const requestFullScreen = () => {
    let documentRequestScreenElement: any = null
    documentRequestScreenElement = document.getElementById(
        'video-contianer'
    ) as HTMLElement & {
        webkitRequestFullScreen(): Promise<void>
        mozRequestFullScreen(): Promise<void>
        msRequestFullScreen(): Promise<void>
    }

    var requestMethod =
        documentRequestScreenElement.requestFullScreen ||
        documentRequestScreenElement.webkitRequestFullScreen ||
        documentRequestScreenElement.mozRequestFullScreen ||
        documentRequestScreenElement.msRequestFullScreen
    if (requestMethod) {
        requestMethod.call(documentRequestScreenElement)
    }

    // js 写法
    // const element = document.getElementById('video-contianer')
    // var requestMethod =
    //     element.requestFullScreen ||
    //     element.webkitRequestFullScreen ||
    //     element.mozRequestFullScreen ||
    //     element.msRequestFullScreen
    // if (requestMethod) {
    //     requestMethod.call(element)
    // } else if (typeof window.ActiveXObject !== 'undefined') {
    //     var wscript = new ActiveXObject('WScript.Shell')
    //     if (wscript !== null) {
    //         wscript.SendKeys('{F11}')
    //     }
    // }
}

const exitFullScreen = () => {
    const documentFullScreenElement = document as Document & {
        mozCancelFullScreen(): Promise<void>
        webkitExitFullscreen(): Promise<void>
        msExitFullscreen(): Promise<void>
    }
    var exitMethod =
        documentFullScreenElement.exitFullscreen ||
        documentFullScreenElement.mozCancelFullScreen ||
        documentFullScreenElement.webkitExitFullscreen ||
        documentFullScreenElement.msExitFullscreen
    if (exitMethod) {
        exitMethod.call(documentFullScreenElement)
    }

    // js 写法
    // var exitMethod =
    //     document.exitFullscreen ||
    //     document.mozCancelFullScreen ||
    //     document.webkitExitFullscreen ||
    //     document.msExitFullscreen
    // if (exitMethod) {
    //     exitMethod.call(document)
    // } else if (typeof window.ActiveXObject !== 'undefined') {
    //     var wscript = new ActiveXObject('WScript.Shell')
    //     if (wscript !== null) {
    //         wscript.SendKeys('{F11}')
    //     }
    // }
}

onUnmounted(() => {
    destory()
})
</script>

<template>
    <div class="mainContainer">
        <video id="video-contianer" autoplay muted controls width="1024" height="576">
            Your browser is too old which doesn't support HTML5 video.
        </video>
        <button @click="load">Load</button>
        <button @click="start">Start</button>
        <button @click="pause">Pause</button>
        <button @click="destory">Destory</button>
        <button @click="screenshot">Screenshot</button>
        <button @click="zoom">Zoom</button>
    </div>
</template>

<style scoped>
.mainContainer {
    display: block;
    width: 1024px;
    margin-left: auto;
    margin-right: auto;
}
</style>

项目地址

项目地址:https://github.com/aibujin/vue3.0-flv.js

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软件测试工程师的工作内容?告诉你们什么是真正的测试工程师

目录 前言 1.何为软件测试工程师&#xff1f; 2.软件测试工程师的职责&#xff1f; 3.为什么要做软件测试&#xff1f; 4.软件测试的前途如何&#xff1f; 5.工具和思维谁更重要&#xff1f; 6.测试和开发相差大吗&#xff1f; 7.成为测试工程师的必备条件 8.测试的分…

局域网远程连接

一根网线连接两台电脑 前言步骤1 设置B“允许远程连接”2 A和B必须在同一个网段下面3 “winr”&#xff0c;输入“mstsc”中4 弹出“远程桌面连接”窗口&#xff0c;输入B的ip地址和B电脑的用户名及密码&#xff08;winL键锁屏&#xff0c;看看B的用户名和密码是什么&#xff0…

【正点原子STM32连载】 第四十五章 FLASH模拟EEPROM实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

第四十五章 FLASH模拟EEPROM实验 STM32本身没有自带EEPROM&#xff0c;但是STM32具有IAP&#xff08;在应用编程&#xff09;功能&#xff0c;所以我们可以把它的FLASH当成EEPROM来使用。本章&#xff0c;我们将利用STM32内部的FLASH来实现第三十六章实验类似的效果&#xff0…

MVTEC 3D dataset

官网&#xff1a;https://www.mvtec.com/company/research/datasets/mvtec-3d-ad/downloads https://www.mvtec.com/company/research/datasets/mvtec-3d-adhttps://www.mvtec.com/company/research/datasets/mvtec-3d-ad 数据大小&#xff1a;13个G 1. 介绍 MVTec 3D异常检测…

OpenCV 学习笔记(C++)(1.4W字)

一切图像皆Mat OpenCV中图像对象的创建与复制 Mat基本结构 Mat对象数据组成&#xff1a;头部和数据部分&#xff0c;头部存储图像的属性&#xff08;大小、宽高、图像类型&#xff1a;浮点数类型、字节类型、16位整型、32位整型、双精度浮点型&#xff0c;通道数量和获取途径…

【Soft-prompt Tuning for Large Language Models to Evaluate Bias 论文略读】

Soft-prompt Tuning for Large Language Models to Evaluate Bias 论文略读 INFORMATIONAbstract1 Introduction2 Related work3 Methodology3.1 Experimental setup 4 Results5 Discussion & Conclusion总结A Fairness metricsB Hyperparmeter DetailsC DatasetsD Prompt …

【CSS3系列】第八章 · 伸缩盒模型

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

服务器配置与操作

服务器配置与操作 一、连接远程服务器 推荐用xshell 或者 finalshell 或者 winSCP 或者 FileZilla xshell下载地址&#xff1a;https://xshell.en.softonic.com/ 二、服务器配置 2.1 安装JDK 2.1 方法一&#xff1a;在线安装 yum list java* yum -y install java-1.8.0-ope…

利用jmeter测试java请求

jmeter和loadrunner一样包含了测试脚本开发、测试执行、以及测试结果统计三个部分。只是jmeter没有脚本开发工具&#xff0c;因此测试java请求的脚本选择在eclipse中进行。 首先介绍如何用eclipse编写接口性能测试脚本。 针对"Java请求"类型的测试&#xff0c;需要…

系列五、NotePad++下载安装

一、下载 链接&#xff1a;https://pan.baidu.com/s/1U2f74vfBJIds7W2wJYnBxg?pwdyyds 提取码&#xff1a;yyds 二、安装 2.1、安装NotePad 解压NotePad-x64.zip至指定目录即可&#xff0c;例如 2.2、安装NppFTP 2.2.1、查看NotePad对应的位数&#xff08;32位or64位&a…

文本分析-使用jieba库实现TF-IDF算法提取关键词

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

程序员找工作难!拿到外包公司的 offer 我应该去么?

引言 前一阵子有一个帖子引起了非常广泛的讨论&#xff0c;描述的就是一个公司的外包工作人员&#xff0c;加班的时候因为吃了公司给员工准备的零食,被公司的HR当场批评&#xff01;这个帖子一发出来&#xff0c;让现在测试行业日益新增的外包公司备受关注。那么外包公司和非外…

驱动开发:内核读写内存多级偏移

让我们继续在《内核读写内存浮点数》的基础之上做一个简单的延申&#xff0c;如何实现多级偏移读写&#xff0c;其实很简单&#xff0c;读写函数无需改变&#xff0c;只是在读写之前提前做好计算工作&#xff0c;以此来得到一个内存偏移值&#xff0c;并通过调用内存写入原函数…

【RF-SSA-LSTM】随机森林-麻雀优化算法优化时间序列预测研究(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

JavaScript内存管理和闭包

1 JavaScript内存管理 2 垃圾回收机制算法 3 闭包的概念理解 4 闭包的形成过程 5 闭包的内存泄漏 一个函数只有调用了外部的变量&#xff0c;才算是闭包。函数内和函数外会写成闭包。 深入JS闭包-闭包的访问过程 <!DOCTYPE html> <html lang"en"> &l…

海气相互作用 - 全球水循环过程及其量级

全球水循环过程及其量级 单位&#xff1a;Sv106m3/s&#xff0c;大气/陆地/海洋(103 km3)径流1.3 Sv≈台湾暖流1.1 Sv≈白令海峡0.9-1.1 Sv 从涡度平衡的角度说明为什么大洋强化发生在西边界而非东边界 有且只有在大洋西边界强化&#xff0c;才可以使得摩擦力产生一个正的涡…

pytorch搭建AlexNet网络实现花分类

pytorch搭建AlexNet网络实现花分类 一、AlexNet网络概述分析 二、数据集准备下载划分训练集和测试集 三、代码model.pytrain.pypredict.py 一、AlexNet网络 概述 使用Dropout的方式在网络正向传播过程中随机失活一部分神经元&#xff0c;以减少过拟合 分析 对其中的卷积层、…

Spring Bean的生命周期解读

目录 1. Spring IOC容器 1.1 Spring IOC 容器的设计 1.1.1 BeanFactory 1.1.2 ApplicationContext 1.2 Spring Bean的生命周期 1.2.1 BeanDefinition 1.2.2 InstantiationAwareBeanPostProcessor和BeanPostProcessor 1.2.3 测试生命周期 1. Spring IOC容器 1.1 Spring …

数据库信息速递 DataStax与谷歌合作将向NoSQL AstraDB引入向量搜索技术

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友会分到2群&#xff08;共…

2023-06-23:redis中什么是缓存击穿?该如何解决?

2023-06-23&#xff1a;redis中什么是缓存击穿&#xff1f;该如何解决&#xff1f; 答案2023-06-23&#xff1a; 缓存击穿是指一个缓存中的热点数据非常频繁地被大量并发请求访问&#xff0c;当该热点数据失效的瞬间&#xff0c;持续的大并发请求无法通过缓存获取到数据&…