| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- import '@/assets/css/videojs.scss';
- import { getRandomString } from 'billd-utils';
- import md5 from 'crypto-js/md5';
- import mpegts from 'mpegts.js';
- import videoJs from 'video.js';
- import Player from 'video.js/dist/types/player';
- import { onMounted, onUnmounted, ref, watch } from 'vue';
- import { SRS_CB_URL_PARAMS } from '@/constant';
- import { useAppStore } from '@/store/app';
- import { usePiniaCacheStore } from '@/store/cache';
- import { useUserStore } from '@/store/user';
- import { createVideo } from '@/utils';
- export * as flvJs from 'flv.js';
- function handlePlayUrl(url: string) {
- const userStore = useUserStore();
- const userInfo = userStore.userInfo;
- const userToken = md5(userStore.token) as string;
- return !userInfo
- ? `${url}?${SRS_CB_URL_PARAMS.randomId}=${getRandomString(8)}`
- : `${url}?${SRS_CB_URL_PARAMS.userToken}=${userToken}&${
- SRS_CB_URL_PARAMS.userId
- }=${userInfo.id!}&${SRS_CB_URL_PARAMS.randomId}=${getRandomString(8)}`;
- }
- export function useFlvPlay() {
- // const flvPlayer = ref<flvJs.Player>();
- const flvPlayer = ref<mpegts.Player>();
- const flvVideoEl = ref<HTMLVideoElement>();
- const cacheStore = usePiniaCacheStore();
- const appStore = useAppStore();
- const initRetryMax = 120;
- const retryMax = ref(initRetryMax);
- const retry = ref(0);
- const retryTimer = ref();
- const retrying = ref(false);
- onMounted(() => {});
- onUnmounted(() => {
- destroyFlv();
- });
- function destroyFlv() {
- if (flvPlayer.value) {
- flvPlayer.value.destroy();
- flvPlayer.value = undefined;
- }
- flvVideoEl.value?.remove();
- clearInterval(retryTimer.value);
- retryMax.value = initRetryMax;
- }
- function setMuted(val) {
- if (flvVideoEl.value) {
- flvVideoEl.value.muted = val;
- }
- if (flvPlayer.value) {
- flvPlayer.value.muted = val;
- }
- }
- function setVolume(val: number) {
- if (flvVideoEl.value) {
- flvVideoEl.value.volume = val / 100;
- }
- if (flvPlayer.value) {
- flvPlayer.value.volume = val / 100;
- }
- }
- function setPlay(val: boolean) {
- if (val) {
- flvVideoEl.value?.play();
- flvPlayer.value?.play();
- } else {
- flvVideoEl.value?.pause();
- flvPlayer.value?.pause();
- }
- }
- watch(
- () => cacheStore.muted,
- (newVal) => {
- setMuted(newVal);
- }
- );
- watch(
- () => cacheStore.volume,
- (newVal) => {
- setVolume(newVal);
- }
- );
- watch(
- () => appStore.play,
- (newVal) => {
- setPlay(newVal);
- }
- );
- function startFlvPlay(data: { flvurl: string }) {
- console.log('startFlvPlay', data.flvurl);
- return new Promise((resolve) => {
- function main() {
- destroyFlv();
- if (mpegts.getFeatureList().mseLivePlayback && mpegts.isSupported()) {
- flvPlayer.value = mpegts.createPlayer({
- type: 'flv', // could also be mpegts, m2ts, flv
- isLive: true,
- url: handlePlayUrl(data.flvurl),
- });
- const videoEl = createVideo({});
- videoEl.addEventListener('play', () => {
- console.log('flv-play');
- });
- videoEl.addEventListener('playing', () => {
- console.log('flv-playing');
- retry.value = 0;
- setMuted(cacheStore.muted);
- setVolume(cacheStore.volume);
- flvVideoEl.value = videoEl;
- resolve('');
- });
- videoEl.addEventListener('loadedmetadata', () => {
- console.log('flv-loadedmetadata');
- });
- flvPlayer.value.attachMediaElement(videoEl);
- flvPlayer.value.load();
- flvPlayer.value.on(mpegts.Events.ERROR, () => {
- console.error('mpegts消息:mpegts.Events.ERROR');
- if (retry.value < retryMax.value && !retrying.value) {
- retrying.value = true;
- destroyFlv();
- retryTimer.value = setTimeout(() => {
- console.error(
- '播放flv错误,重新加载,剩余次数:',
- retryMax.value - retry.value
- );
- retry.value += 1;
- retrying.value = false;
- main();
- }, 1000);
- }
- });
- flvPlayer.value.on(mpegts.Events.MEDIA_INFO, () => {
- console.log('mpegts消息:mpegts.Events.MEDIA_INFO');
- });
- try {
- console.log(`开始播放flv,muted:${cacheStore.muted}`);
- flvPlayer.value.play();
- } catch (err) {
- console.error('flv播放失败');
- console.log(err);
- }
- } else {
- console.error('不支持flv');
- }
- }
- main();
- });
- }
- return { flvPlayer, flvVideoEl, startFlvPlay, destroyFlv };
- }
- export function useHlsPlay() {
- const hlsPlayer = ref<Player>();
- const hlsVideoEl = ref<HTMLVideoElement>();
- const cacheStore = usePiniaCacheStore();
- const appStore = useAppStore();
- const initRetryMax = 120;
- const retryMax = ref(initRetryMax);
- const retry = ref(0);
- const retryTimer = ref();
- const retrying = ref(false);
- onMounted(() => {});
- onUnmounted(() => {
- destroyHls();
- });
- function destroyHls() {
- if (hlsPlayer.value) {
- hlsPlayer.value.dispose();
- hlsPlayer.value = undefined;
- }
- hlsVideoEl.value?.remove();
- clearInterval(retryTimer.value);
- retryMax.value = initRetryMax;
- }
- function setMuted(val: boolean) {
- if (hlsVideoEl.value) {
- hlsVideoEl.value.muted = val;
- }
- if (hlsPlayer.value) {
- hlsPlayer.value.muted(val);
- }
- }
- function setVolume(val: number) {
- if (hlsVideoEl.value) {
- hlsVideoEl.value.volume = val / 100;
- }
- if (hlsPlayer.value) {
- hlsPlayer.value.volume(val / 100);
- }
- }
- function setPlay(val: boolean) {
- if (val) {
- hlsVideoEl.value?.play();
- hlsPlayer.value?.play();
- } else {
- hlsVideoEl.value?.pause();
- hlsPlayer.value?.pause();
- }
- }
- watch(
- () => cacheStore.muted,
- (newVal) => {
- setMuted(newVal);
- }
- );
- watch(
- () => cacheStore.volume,
- (newVal) => {
- setVolume(newVal);
- }
- );
- watch(
- () => appStore.play,
- (newVal) => {
- setPlay(newVal);
- }
- );
- function startHlsPlay(data: { hlsurl: string }) {
- return new Promise((resolve) => {
- function main() {
- console.log('startHlsPlay', data.hlsurl);
- destroyHls();
- const videoEl = createVideo({
- muted: cacheStore.muted,
- autoplay: true,
- });
- hlsPlayer.value = videoJs(
- videoEl,
- {
- sources: [
- {
- src: handlePlayUrl(data.hlsurl),
- type: 'application/x-mpegURL',
- },
- ],
- },
- function () {
- try {
- // console.log(`开始播放hls,muted:${cacheStore.muted}`);
- hlsPlayer.value?.play();
- } catch (err) {
- console.error('hls播放失败');
- console.log(err);
- }
- }
- );
- hlsPlayer.value?.on('error', () => {
- console.log('hls-error');
- if (retry.value < retryMax.value && !retrying.value) {
- retrying.value = true;
- retryTimer.value = setTimeout(() => {
- console.error(
- '播放hls错误,重新加载,剩余次数:',
- retryMax.value - retry.value
- );
- retry.value += 1;
- retrying.value = false;
- main();
- }, 1000);
- }
- });
- hlsPlayer.value?.on('play', () => {
- console.log('hls-play');
- // console.log(hlsPlayer.value?.videoHeight()); // 获取到的是0!
- });
- hlsPlayer.value?.on('playing', () => {
- console.log('hls-playing');
- setMuted(cacheStore.muted);
- setVolume(cacheStore.volume);
- retry.value = 0;
- // console.log(hlsPlayer.value?.videoHeight()); // 获取到的是正确的!
- const childNodes = hlsPlayer.value?.el().childNodes;
- if (childNodes) {
- childNodes.forEach((item) => {
- if (item.nodeName.toLowerCase() === 'video') {
- // @ts-ignore
- hlsVideoEl.value = item;
- }
- });
- }
- resolve('');
- });
- hlsPlayer.value?.on('loadedmetadata', () => {
- console.log('hls-loadedmetadata');
- });
- }
- main();
- });
- }
- return { hlsPlayer, hlsVideoEl, startHlsPlay, destroyHls };
- }
|