vue 3.0 + vite + flv 视频流播放

news2024/11/23 20:15:26

官方提供的 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

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

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

相关文章

CASAIM 与ABB 达成三维数字化测量技术合作,CASAIM 国有专业尺寸检测实验室助力机器人轨道检测

近期&#xff0c;CASAIM与ABB达成三维数字化测量技术合作&#xff0c;CASAIM 国有专业尺寸检测实验室助力ABB完成机器人轨道检测&#xff0c;提高机器人的运动精度和稳定性。 ABB集团位列全球500强企业&#xff0c;是全球领先的工业机器人制造商之一&#xff0c;致力于提供高质…

ModaHub魔搭社区:向量数据库Milvus部署运维问题教程(二)

目录 在 Windows 安装 pymilvus 报错&#xff0c;如何解决&#xff1f; 内网环境&#xff0c;即离线方式&#xff0c;能否部署 Milvus 服务&#xff1f; 在多个 Milvus 节点接入 Pushgateway 的情况下如何进行区分数据来源&#xff1f; 我应该使用 SQLite 还是 MySQL 进行元…

基于群组实现从 Azure AD 到极狐GitLab 的单点登录

目录 配置单点登录 在 Azure AD 中创建企业应用 SAML 基础配置 配置 Azure “Attributes & Claims” 配置用户同步 在极狐GitLab 创建 SCIM Token 配置 Azure Provisioning Azure 手动用户预配 测试单点登录 Azure 自动用户同步 配置群组同步 配置 SAML 群组链…

【算法基础】快速排序(模板)

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;【C/C】算法 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵 希望大佬指点一二 如果文章对你有…

力扣题库刷题笔记17--电话号码的字母组合

1、题目如下&#xff1a; 2、个人Python代码实现&#xff1a; 还是先记录一下思路&#xff0c;首先这种类型的题&#xff0c;需要自定义一个字典对应题目中的电话号码和数字。其次&#xff0c;个人的思路是&#xff0c;先读取字符串第一个字符&#xff08;digits[0]&#xff09…

云原生(第二篇)k8s-二进制搭建

准备五台机器&#xff1a; master01&#xff1a;192.168.169.10 node01&#xff1a;192.168.169.40 node02&#xff1a;192.168.169.50 master02&#xff1a;192.168.169.60 负载均衡nginxkeepalive01&#xff08;master&#xff09;&#xff1a;192.168.169.20 负载均衡…

记一次Native memory leak排查过程 | 京东云技术团队

1 问题现象 路由计算服务是路由系统的核心服务&#xff0c;负责运单路由计划的计算以及实操与计划的匹配。在运维过程中&#xff0c;发现在长期不重启的情况下&#xff0c;有TP99缓慢爬坡的现象。此外&#xff0c;在每周例行调度的试算过程中&#xff0c;能明显看到内存的上涨…

Windows开启telnect

1、Telnet是什么&#xff1f; Telnet 是一种网络协议&#xff0c;用于通过网络远程登录到远程计算机或设备上。它允许用户在本地计算机上使用命令行界面&#xff08;命令提示符&#xff09;与远程主机进行交互&#xff0c;就像直接在远程主机上操作一样。Telnet 协议使用 TCP/I…

【需求实现】Tensorflow2的曲线拟合(三):Embedding层

文章目录 导读Embedding的维度问题Embedding的输入输出比较容易踩的坑input_shape与input_length的对应关系built属性 导读 这是填曲线拟合第一篇的坑&#xff0c;有关Embedding层的问题。 Embedding的维度问题 首先是上次我们提到的Embedding层&#xff0c;他确实能够做到将…

预约Oracle OCP认证考试的保姆式流程

Oracle OCP认证考试的预约流程涉及到Oracle的SLS培训记录&#xff0c;因此相当复杂。本文进行了详细地说明&#xff0c;每一步都有截图&#xff0c;有需要的同学建议收藏。 关于号主&#xff0c;姚远 Oracle ACE&#xff08;Oracle和MySQL数据库方向&#xff09;。Oracle MAA…

智能体重秤方案PCBA方案设计

智能体重秤是一款高精度、便捷、多功能的健康管理工具&#xff0c;旨在帮助用户监测和控制体重&#xff0c;达到健康管理与减肥的目的。该产品融合了先进的科技技术&#xff0c;结合了人体工程学设计&#xff0c;具有美观、易用的特点。以下将从结构、参数、原理和应用方面为大…

电涌(浪涌)保护器防雷保护级别

浪涌保护器实际就是压敏电阻&#xff0c;具有高通低阻的特性。当电网在不超过最大持续运行电压的情况下运行时&#xff0c;两个电极之间呈高阻状态。由于雷击的能量是非常巨大的&#xff0c;需要通过分级泄放的方法&#xff0c;将雷击能量逐步泄放到大地。 第一级防雷器可以对…

mmyolo框架实现在VOC数据集上复现Yolov6教程(详细)

写在开头&#xff0c;最近学习mmyolo的框架&#xff0c;想着它能将所有配置都写在一个config文件里&#xff0c;只需要改配置文件就可以改动模型&#xff0c;感觉挺方便的。 就想着Yolov6用mmyolo框架来实现,但mmyolo并没有提供v6的voc实现配置&#xff0c;v5是有的(看下图)&am…

软件测试技能,JMeter压力测试教程,取样器之测试活动(十八)

目录 前言 一、测试活动(Test Action) 二、Pause 设置暂停 三、Stop 停止 四、循环设置 五、跨线程组使用 前言 如果想在请求之后加等待时间如何做呢&#xff1f; 如果希望在 sampler 执行完之后再等待&#xff0c;则可使用取样器里面的测试活动 (Test Action) 一、测…

10个Salesforce集成项目最佳实践,助力成为专家!

随着企业越来越关注数据驱动的决策方法&#xff0c;集成多个系统成为了Salesforce 实施不可或缺的一部分。无论该项目是Salesforce的传统CRM迁移还是新的CRM实施&#xff0c;Salesforce CRM与ERP以及其他业务关键系统的集成都是需要考虑的重要策略。 集成项目的成功很大程度上…

Vue-pdf踩坑记录

最近在公司的一个项目中&#xff0c;需要在线预览PDF文件。基于vue-admin-electron的模板中开发。开发机系统为Windows&#xff0c;使用的框架为electron-vue。 坑1&#xff1a;在通过vue-router路由到含有vue-pdf组件的页面时报&#xff1a;“syntaxError: Unexpected token …

《移动互联网技术》 第十章 系统与通信: 掌握Android系统的分层架构设计思想和基于组件的设计模式

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

玩转代码|三个惊艳的黑科技代码,每一行代码都有惊讶的效果

目录 显示忘记密码 解除网页限制 去除视频logo 今日优质代码推荐 实现效果 实现过程 1. 简单的 Html 和 CSS 2. 创建 canvas画布 3. 获取鼠标点击位置 4. 实现鼠标点击产生烟花的初级形态 5. 实现烟花散开 6. 实现拖尾效果以及随机颜色 7. 实现烟花重力下坠 8. 实…

深度学习模型训练的全流程

目标是使用Pytorch来完成CNN的训练和验证过程&#xff0c;CNN网络结构。需要完成的逻辑结构如下&#xff1a; 构造训练集和验证集&#xff1b; 每轮进行训练和验证&#xff0c;并根据最优验证集精度保存模型。 # 将自定义的Dataset封装成一个Batch Size大小的Tensor&#xf…