Browse Source

调整测试的默认播放器

kwl 2 tuần trước cách đây
mục cha
commit
84ed3ecac8

+ 14 - 1
src/main/java/com/jttserver/service/ManagerWebServer.java

@@ -48,7 +48,11 @@ public class ManagerWebServer {
      * 检查资源文件是否存在
      */
     private void checkResources() {
-        String[] resourceFiles = { "devices.html", "player.html", "playerWhthoutAudio.html", "offline_player.html", "mpegts.js", "jessibuca/demo.html", "jessibuca/jessibuca.js" };
+        String[] resourceFiles = { 
+            "devices.html", "player.html", "playerWhthoutAudio.html", "offline_player.html", "mpegts.js", 
+            "jessibuca/demo.html", "jessibuca/jessibuca.js", "jessibuca/decoder.js", "jessibuca/decoder.wasm", 
+            "jessibuca/jessibuca.d.ts", "jessibuca/player.html"
+        };
         for (String file : resourceFiles) {
             try (InputStream inputStream = ManagerWebServer.class.getClassLoader().getResourceAsStream("web/" + file)) {
                 if (inputStream == null) {
@@ -392,10 +396,19 @@ public class ManagerWebServer {
                     response.headers().set(HttpHeaderNames.CONTENT_TYPE, "image/jpeg");
                 } else if (fileName.endsWith(".png")) {
                     response.headers().set(HttpHeaderNames.CONTENT_TYPE, "image/png");
+                } else if (fileName.endsWith(".wasm")) {
+                    response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/wasm");
+                    // 为WebAssembly文件添加必要的CORS头信息
+                    response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
                 } else {
                     response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/octet-stream");
                 }
                 
+                // 为所有静态资源添加CORS头信息
+                response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
+                response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, OPTIONS");
+                response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_HEADERS, "Content-Type, Authorization");
+                
                 response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, content.length);
                 ctx.writeAndFlush(response);
             } catch (IOException e) {

+ 1 - 1
src/main/resources/web/devices.html

@@ -194,7 +194,7 @@
                         playBtn.className = 'btn btn-player';
                         playBtn.onclick = function () {
                             // 构建带参数的URL(包含 prefix)
-                            const url = `/player.html?sim=${encodeURIComponent(device.simCardNumber || '')}&channel=${encodeURIComponent(device.logicChannelNumber)}&prefix=${encodeURIComponent(device.prefix || '')}`;
+                            const url = `/jessibuca/player.html?sim=${encodeURIComponent(device.simCardNumber || '')}&channel=${encodeURIComponent(device.logicChannelNumber)}&prefix=${encodeURIComponent(device.prefix || '')}`;
                             // 使用bindOpenInPopup函数打开播放器
                             openPlayerInPopup(url, 'PlayerWindow');
                         };

+ 211 - 0
src/main/resources/web/jessibuca/player.html

@@ -0,0 +1,211 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <meta charset="UTF-8">
+    <title>Jessibuca 播放器</title>
+    <script src="./jessibuca.js"></script>
+    <style>
+        .root {
+            display: flex;
+            place-content: center;
+            margin-top: 3rem;
+        }
+        .container-shell {
+            backdrop-filter: blur(5px);
+            background: hsla(0, 0%, 50%, 0.5);
+            padding: 30px 4px 10px 4px;
+            /* border: 2px solid black; */
+            width: auto;
+            position: relative;
+            border-radius: 5px;
+            box-shadow: 0 10px 20px;
+        }
+        .container-shell:before {
+            content: "jessibuca demo player";
+            position: absolute;
+            color: darkgray;
+            top: 4px;
+            left: 10px;
+            text-shadow: 1px 1px black;
+        }
+        #container {
+            background: rgba(13, 14, 27, 0.7);
+            width: 640px;
+            height: 398px;
+        }
+        .input {
+            display: flex;
+            margin-top: 10px;
+            color: white;
+            place-content: stretch;
+        }
+        .input2 {
+            bottom: 0px;
+        }
+        .input input {
+            flex: auto;
+        }
+        .err {
+            position: absolute;
+            top: 40px;
+            left: 10px;
+            color: red;
+        }
+        .option {
+            position: absolute;
+            top: 4px;
+            right: 10px;
+            display: flex;
+            place-content: center;
+            font-size: 12px;
+        }
+        .option span {
+            color: white;
+        }
+        .page {
+            background: white;
+            background-repeat: no-repeat;
+            background-position: top;
+        }
+        @media (max-width: 720px) {
+            #container {
+                width: 90vw;
+                height: 52.7vw;
+            }
+        }
+    </style>
+</head>
+<body class="page">
+<div class="root">
+    <div class="container-shell">
+        <div id="container"></div>
+        <div class="input">
+            <div>输入URL:</div>
+            <input
+                autocomplete="on"
+                id="playUrl"
+                value=""
+            />
+            <button id="play">播放</button>
+            <button id="pause" style="display: none">停止</button>
+        </div>
+        <div class="input" style="line-height: 30px">
+            <button id="destroy">销毁</button>
+        </div>
+    </div>
+</div>
+<script>
+    var $player = document.getElementById('play');
+    var $pause = document.getElementById('pause');
+    var $playHref = document.getElementById('playUrl');
+    var $container = document.getElementById('container');
+    var $destroy = document.getElementById('destroy');
+    var showOperateBtns = false; // 是否显示按钮
+    var forceNoOffscreen = true; //
+    var jessibuca = null;
+
+    // 获取URL参数
+    function getUrlParams() {
+        const params = new URLSearchParams(window.location.search);
+        return {
+            sim: params.get('sim') || '',
+            channel: params.get('channel') || '',
+            prefix: params.get('prefix') || ''
+        };
+    }
+
+    // 构建播放URL
+    function buildPlayUrl(params) {
+        if (!params.sim || !params.channel || !params.prefix) {
+            return '';
+        }
+        
+        // 根据参数构建WebSocket URL
+        const baseUrl = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
+        const host = window.location.hostname;
+        const path = `${params.prefix}${encodeURIComponent(params.sim)}-${encodeURIComponent(params.channel)}`;
+        const port = 18090
+        
+        let url = `${baseUrl}${host}:${port}${path}.flv`;
+        
+        return url;
+    }
+
+    // 页面加载时自动填充URL
+    function autoFillPlayUrl() {
+        const params = getUrlParams();
+        if (params.sim && params.channel) {
+            const playUrl = buildPlayUrl(params);
+            if (playUrl) {
+                $playHref.value = playUrl;
+                // 自动开始播放
+                setTimeout(() => {
+                    $player.click();
+                }, 500);
+            }
+        }
+    }
+    function create() {
+        jessibuca = null;
+        jessibuca = new Jessibuca({
+            container: $container,
+            videoBuffer: 0.2, // 缓存时长
+            isResize: false,
+            text: "",
+            loadingText: "",
+            useMSE: false,
+            debug: true,
+            showBandwidth: showOperateBtns, // 显示网速
+            operateBtns: {
+                fullscreen: showOperateBtns,
+                screenshot: showOperateBtns,
+                play: showOperateBtns,
+                audio: true,
+                recorder: false
+            },
+            forceNoOffscreen: forceNoOffscreen,
+            isNotMute: false,
+        },);
+        jessibuca.on('audioInfo', function (audioInfo) {
+            console.log('audioInfo',audioInfo);
+        })
+        jessibuca.on('videoInfo', function (videoInfo) {
+            console.log('videoInfo',videoInfo);
+        })
+        $player.style.display = 'inline-block';
+        $pause.style.display = 'none';
+        $destroy.style.display = 'none';
+    }
+    create();
+    $player.addEventListener('click', function () {
+        var href = $playHref.value;
+        if (href) {
+            jessibuca.play(href);
+            $player.style.display = 'none';
+            $pause.style.display = 'inline-block';
+            $destroy.style.display = 'inline-block';
+        }
+    }, false)
+    $pause.addEventListener('click', function () {
+        $player.style.display = 'inline-block';
+        $pause.style.display = 'none';
+        jessibuca.pause();
+    })
+    $destroy.addEventListener('click', function () {
+        if (jessibuca) {
+            jessibuca.destroy().then(()=>{
+                create();
+            });
+        }
+        else {
+            create();
+        }
+    })
+
+    // 页面加载完成后自动填充URL并开始播放
+    document.addEventListener('DOMContentLoaded', function() {
+        autoFillPlayUrl();
+    });
+</script>
+</body>
+</html>