Ai
3 Star 1 Fork 0

广州灵派科技有限公司/webFlex

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
player.php 11.75 KB
一键复制 编辑 原始数据 按行查看 历史
wangc 提交于 2025-09-12 10:38 +08:00 . 20250912
<!doctype html>
<html lang="uft-8">
<head>
<?php include ("./public/head.inc") ?>
</head>
<body>
<?php include ("./public/menu.inc") ?>
<div data-simplebar>
<main class="page-content player" id="app" v-cloak>
<div class="row">
<div class="col-lg-10">
<div class="card">
<div class="card-body" >
<div class="row">
<div class="d-flex align-items-center gap-3 px-2 py-1">
<div class="flex-grow-0">
<label class="fw-bold">
<cn>频道</cn>
<en>Channel</en>:
</label>
</div>
<div class="flex-grow-0">
<select class="form-select" v-model="activeChnId" @change="onChangePlayerChn">
<option v-for="(item,index) in handleActivePlayerConf" :value="item.id" :data-attr-codec="item.encv.codec" :data-attr-suffix="item.stream.suffix" :data-attr-audio="item._hadAudio" :data-attr-protocol="item.stream.rtmp?'rtmp':'webrtc'">{{item.name}}</option>
</select>
</div>
<div class="flex-grow-0" v-if="playerCodec === 'h265'">
<label class="fw-bold">
<cn>缓冲</cn>
<en>Buffer</en>:
</label>
</div>
<div class="flex-grow-0" v-if="playerCodec === 'h265'">
<div class="input-group" style="width: 100px;">
<input type="text" class="form-control" v-model="bufferTime" @change="onChangeBufferTime">
<span class="input-group-text">ms</span>
</div>
</div>
<div class="flex-grow-0">
<label class="fw-bold">
<cn>视频编码: {{playerCodec.toUpperCase()}}</cn>
<en>Video: {{playerCodec.toUpperCase()}}</en>
</label>
</div>
<div class="flex-grow-0">
<label class="fw-bold">
<cn>音频编码: {{audioCodec.toUpperCase()}}</cn>
<en>Audio: {{audioCodec.toUpperCase()}}</en>
</label>
</div>
<div class="flex-grow-0">
<label class="fw-bold">
<cn>播放协议: {{playerProtocol.toUpperCase()}}</cn>
<en>Protocol: {{playerProtocol.toUpperCase()}}</en>
</label>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12 mt-2 mb-2">
<h5-player :url="playerUrl" :canplay="true" :codec="playerCodec" :audio="playerAudio" :protocol="playerProtocol" :buffer="bufferTime"></h5-player>
</div>
</div>
<div class="row mt-2">
<div class="col-lg-12 tips">
<cn>1、使用h5播放器,需要在串流输出页面开启对应频道的rtmp或webrtc协议流</cn>
<en>1. To use H5 player, enable the RTMP or WebRTC protocol for the corresponding video channel</en>
</div>
<div class="col-lg-12 tips">
<cn>2、播放h265编码的视频流对电脑配置要求较高,如果遇到音视频卡顿问题,请更换性能更好的电脑播放</cn>
<en>2. Playing H265 encoded video stream has high requirements for computer configuration. If you encounter audio and video delay problem, please replace the device with better performance</en>
</div>
<div class="col-lg-12 tips">
<cn>3、为当前频道创建一个全屏播放快捷方式,请点击此处<a href="#" @click="onDownloadPlayShortcut" style="text-decoration: underline;">下载</a></cn>
<en>3. Create a fullscreen play shortcut for the current channel. Please click <a href="#" @click="onDownloadPlayShortcut" style="text-decoration: underline;">here</a> to download.</en>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
<?php include ("./public/foot.inc") ?>
<script type="module">
import { useDefaultConf } from "./assets/js/vue.hooks.js?hash=89523e901";
import { ignoreCustomElementPlugin,filterKeywordPlugin,h5PlayerComponent } from "./assets/js/vue.helper.js?hash=68eefc36f"
import {clearReactiveArray, getUrlParam, rpc} from "./assets/js/lp.utils.js?hash=e82520f08"
import vue from "./assets/js/vue.build.js?hash=879ea7dbc";
const {createApp,ref,reactive,watch,watchEffect,computed,onMounted} = vue;
const app = createApp({
components:{
"h5-player": h5PlayerComponent
},
setup(props,context) {
const { defaultConf } = useDefaultConf();
let chnId = parseInt(getUrlParam("channel"));
const state = {
activeChnId : ref(0),
playerUrl: ref(""),
playerCodec: ref("none"),
playerAudio: ref(false),
audioCodec: ref("none"),
playerProtocol:ref(""),
bufferTime:ref(200),
audioState:reactive([])
}
const unwatch = watchEffect(() => {
if(defaultConf.length > 0 && state.audioState.length > 0) {
for(let i=0;i<defaultConf.length;i++) {
let item = defaultConf[i];
if(chnId && item.id !== chnId)
continue;
if (item.enable && (item.stream.rtmp || item.stream.webrtc)) {
const audio = state.audioState.find(it => it.id === item.id);
const protocol = item.stream.rtmp ? 'rtmp' : 'webrtc';
state.activeChnId.value = item.id;
if(protocol === 'webrtc')
state.playerUrl.value = `http://${window.location.host}/webrtc?app=live&stream=${item.stream.suffix}`;
else
state.playerUrl.value = `http://${window.location.host}/flv?app=live&stream=${item.stream.suffix}`;
state.playerCodec.value = item.encv.codec;
state.playerAudio.value = !audio.mute;
state.playerProtocol.value = protocol;
state.audioCodec.value = item.enca.codec;
if(item.type === 'net') {
if(!item.net.decodeA)
state.audioCodec.value = 'Source';
}
break;
}
}
unwatch();
}
})
const handleActivePlayerConf = computed(()=>{
return defaultConf.filter(item => {
const audio = state.audioState.find(it => it.id === item.id);
item._hadAudio = false;
if(audio)
item._hadAudio = !audio.mute;
return !!(item.enable && item.type !=="ndi" && (item.stream.rtmp || item.stream.webrtc));
})
})
const onChangeBufferTime = () => {
localStorage.setItem("bufferTime",state.bufferTime.value);
}
const onChangePlayerChn = (event) => {
const selectElement = event.target;
const selectedOption = selectElement.options[selectElement.selectedIndex];
const protocol = selectedOption.getAttribute('data-attr-protocol');
const suffix = selectedOption.getAttribute('data-attr-suffix');
if(protocol === 'webrtc')
state.playerUrl.value = `http://${window.location.host}/webrtc?app=live&stream=${suffix}`;
else
state.playerUrl.value = `http://${window.location.host}/flv?app=live&stream=${suffix}`;
state.playerCodec.value = selectedOption.getAttribute('data-attr-codec');
state.playerAudio.value = selectedOption.getAttribute('data-attr-audio');
state.playerProtocol.value = protocol;
const conf = defaultConf.find(item => item.id === parseInt(selectElement.value));
state.audioCodec.value = conf.enca.codec;
if(conf.type === 'net') {
if(!conf.net.decodeA)
state.audioCodec.value = 'Source';
}
}
const onDownloadPlayShortcut = () => {
const href = "http://"+window.location.host+"/fplayer.php?channel="+state.activeChnId.value;
let content = `[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,2
[InternetShortcut]
IDList=
URL=${href}`;
content = content.replace(/^\s+/gm, '');
const blob = new Blob([content], { type: 'text/plain' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
let chnName = defaultConf[state.activeChnId.value].name;
link.download = chnName+"-full-player.url";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
onMounted(()=>{
let buffer = localStorage.getItem("bufferTime");
if(buffer !== null && buffer !== undefined)
state.bufferTime.value = buffer;
rpc("enc.getAudioState").then(data => {
clearReactiveArray(state.audioState)
state.audioState.push(...data);
})
})
return {...state,handleActivePlayerConf,onChangePlayerChn,onChangeBufferTime,onDownloadPlayShortcut}
}
});
app.use(ignoreCustomElementPlugin);
app.use(filterKeywordPlugin);
app.mount('#app');
</script>
</body>
</html>
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/LinkPi/webflex.git
git@gitee.com:LinkPi/webflex.git
LinkPi
webflex
webFlex
master

搜索帮助