m3u8视频文件夹COS上传及播放(无论是TCplayer 还是video.js在手机浏览器端都无法兼容, 特别是ios端)
- 创作的背景: 原来使用的mp4来进行视频上传 播放和下载, 由于腾讯云视频流量高峰期一周的收费达到5000元左右, 特提出优化方案, 上传视频的时候上传mp4 和 m3u8 各一份, 视频在线播放使用TCplayer或videojs 进行m3u8视频播放, 下载时下载mp4格式视频, 以此方案来减少腾讯云流量来减少支出
- 经过多篇文章的阅读无果后又与腾讯客服反复沟通实现前端上传mp4转换成的m3u8视频文件夹, 并实现m3u8视频播放
1. 找到项目的index.html入口文件引入下边样式和js, 放入标签内即可
<link async href="https://web.sdk.qcloud.com/player/tcplayer/release/v4.2.2/tcplayer.min.css" rel="stylesheet" />
<script async src="https://web.sdk.qcloud.com/player/tcplayer/release/v4.2.2/libs/hls.min.0.13.2m.js"></script>
<script async src="https://web.sdk.qcloud.com/player/tcplayer/release/v4.2.2/tcplayer.v4.2.2.min.js"></script>
2. mp4文件上传常规上传即可, 在此特别说明m3u8文件夹cos上传
var COS = require("cos-js-sdk-v5")
import uuid from 'uuid'
let Bucket = ""
let Region = ""
import fetch from "@/utils/request";
import { ElLoading } from 'element-plus'
let serviceModl = '/content'
let loadingOptions = {
text: "正在努力上传,请稍等...",
lock: true,
spinner: "el-icon-loading",
background: "rgba(255, 255, 255, 0.5)",
};
let filePath = '/digital-admin/';
export function getCosSTS (data) {
return fetch({
url: '自己的后端接口地址',
method: "POST",
data: data
})
}
export function initCos () {
return new Promise((resolve) => {
getCosSTS().then(res => {
Bucket = res.data.bucketName;
Region = res.data.endpoint;
let cosObj = {
TmpSecretId: res.data.credentials.tmpSecretId,
TmpSecretKey: res.data.credentials.tmpSecretKey,
SecurityToken: res.data.credentials.sessionToken,
StartTime: res.data.startTime,
ExpiredTime: res.data.expiredTime,
};
let client = new COS({
getAuthorization: function (options, callback) {
callback(cosObj);
}
})
resolve(client)
})
})
}
export async function uploadFilesToCos (files, fileName, size, cos) {
let filesArr = []
for (var key in files) {
if (files[key].size) {
filesArr.push({
Bucket: Bucket,
Region: Region,
Key: filePath + files[key].name,
Body: files[key],
onTaskReady: function (taskId) {
},
Headers: {
'x-cos-meta-test': 123
}
})
}
}
return new Promise(resolve => {
ElLoading.service(loadingOptions);
cos.uploadFiles(
{
files: filesArr,
SliceSize: 1024 * 1024 * 1024,
},
function (err, data) {
ElLoading.service(loadingOptions).close();
console.log('data', data)
if (data.files && data.files.length > 0) {
data.files.forEach(item => {
let ary = item.data.Location.split('.')
let type = ary[ary.length - 1]
if (type === 'm3u8') {
let fileData = {
url: filePath + fileName,
size: size,
name: fileName,
key: filePath + fileName,
}
resolve(fileData)
}
})
}
}
)
})
}
<el-button type="primary" @click="m3u8Upload" style="margin-left: 30px;">上传m3u8</el-button>
<input type="file" id="m3u8Upload" webkitdirectory style="position: absolute; left: 1000000px" @change="m3u8UploadChange($event)">
import {onMounted, ref, reactive, watch} from 'vue'
import { uploadFilesToCos } from "@/api/cos.js";
const cosClient = null
const fileList = ref([])
onMounted(() => {
initOss().then(res=>{
cosClient = res;
})
})
const m3u8Upload = () => {
let element = document.getElementById('m3u8Upload')
element.value = null
element.click()
}
const m3u8UploadChange = ($event) => {
console.log($event)
let fileName = ''
let size = 0
let files = $event.target.files
if (files) {
for (let key in files) {
if (files[key].type) {
fileName = files[key].name
}
if (typeof files[key].size === 'number') {
size += files[key].size
}
}
if (size > 1024 * 1024 * 1024) {
return ElMessage.error('附件大小不可超过1G')
}
uploadFilesToCos(files, fileName, size, cosClient).then(res=>{
if(res && res.url){
console.log('res', res)
fileList.value.push({
name: res.name,
url: res.url
})
}
})
}
}
3. 播放m3u8 视频
- 3.1 使用TCplayer进行视频播放(上边第一步index.html导入的css和js就是TCplayer播放插件
<video id="player-container-id" width="800" height="450" preload="auto" playsinline webkit-playsinline></video>
let player = ref(null)
function m3u8Player(url) {
setTimeout(() => {
player.value = TCPlayer(document.getElementById('player-container-id'), {
reportable: false,
})
player.value.src(url);
console.log('player', player.value)
},100)
}
function m3u8Close() {
if (player.value) {
player.value.pause()
player.value = null
}
}
- 3.2 使用video.js进行m3u8格式视频播放
npm install video.jst@7.13.3 videojs-contrib-hls@5.15.0 videojs-flash@2.2.1
<div class="video-box play-box" ref="videoBox" v-if="showPlayer">
<video
id="videoPlayer"
ref='videoPlayer'
disablePictureInPicture
controlsList="nodownload"
class="play-back video-js vjs-default-skin vjs-big-play-centered"
controls
preload="none">
</video>
</div>
import Videojs from "video.js"
const myPlayer = ref(null)
function closeVideo () {
myPlayer.value.dispose()
},
async function initVideo(url) {
let options = {
autoplay: true,
controls: true,
sources: [
{
src: url,
type: "application/x-mpegURL"
}
]
};
myPlayer.value = Videojs("videoPlayer", options);
},