如何通过HTML的input标签获取HLS视频源并正常播放
问题分析与解决方案
你遇到的代码问题主要有以下几点:
核心问题:HLS关联资源无法加载
你只通过input选择了stream.m3u8文件,但加密HLS播放需要依赖同目录下的stream.m3u8.key密钥文件和所有stream.ts分片文件。浏览器通过URL.createObjectURL()生成的地址只能访问单个选中的文件,无法获取其他未被选中的关联资源,导致播放器找不到密钥和分片,自然无法播放。
代码实现的其他问题
Video.js源更新方式错误
直接修改原生video元素的src属性,没有使用Video.js提供的API来更新媒体源,会导致Video.js播放器无法正确识别和解析新的源。缺少HLS播放插件
你使用的Video.js 7.4.1版本默认不包含HLS播放支持,需要额外引入videojs-contrib-hls插件才能解析.m3u8格式的流媒体。播放器初始化时机问题
在页面加载时就初始化了Video.js播放器,但此时video元素处于隐藏状态,可能导致播放器初始化不完整,后续更新源时出现异常。
修正后的代码实现
要实现本地加密HLS的播放,你需要让用户选择整个HLS资源所在的文件夹(而非单个m3u8文件),同时调整Video.js的使用方式:
<html> <head> <link href="https://vjs.zencdn.net/7.4.1/video-js.css" rel="stylesheet"> <script src="https://vjs.zencdn.net/7.4.1/video.min.js"></script> <!-- 引入HLS播放插件 --> <script src="https://cdn.jsdelivr.net/npm/videojs-contrib-hls@5.15.0/dist/videojs-contrib-hls.min.js"></script> </head> <body> <label for="input">选择HLS资源所在的文件夹:</label> <!-- 允许选择文件夹 --> <input type="file" id="input" name="input_video" webkitdirectory directory> <video id="video" class="video-js vjs-default-skin" width="640" height="360" controls style="display: none;"></video> <script> let player; document.getElementById("input").addEventListener("change", function() { const files = this.files; let m3u8File = null; // 在选中的文件中找到m3u8播放列表 for (let file of files) { if (file.name === 'stream.m3u8') { m3u8File = file; break; } } if (!m3u8File) { alert("未找到stream.m3u8文件"); return; } // 创建文件系统访问的URL const m3u8Url = URL.createObjectURL(m3u8File); const videoEl = document.getElementById("video"); // 初始化或更新Video.js播放器 if (!player) { player = videojs(videoEl); } // 使用Video.js API更新源 player.src({ src: m3u8Url, type: 'application/x-mpegURL' }); videoEl.style.display = "block"; player.play(); }); </script> </body> </html>
注意事项
- 浏览器对本地文件夹的访问有安全限制,需要用户主动选择整个HLS资源所在的文件夹,且该功能依赖浏览器对
webkitdirectory/directory属性的支持(主流浏览器均已支持)。 - 确保所有HLS关联文件(m3u8、key、ts)都在同一个文件夹下,且m3u8文件中对key和ts的引用是相对路径(如
./stream.m3u8.key、./stream_001.ts)。
内容的提问来源于stack exchange,提问作者Saeed Eisakhani
相关产品推荐
相关产品推荐

