|
|
@@ -191,6 +191,12 @@ const processCover = async (url: string): Promise<void> => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+// 判断是否为标准的 HLS 流地址
|
|
|
+const isStandardHlsUrl = (url: string): boolean => {
|
|
|
+ // 简单判断:只要包含 .m3u8 就是 HLS 流
|
|
|
+ return url.includes(".m3u8");
|
|
|
+};
|
|
|
+
|
|
|
// 处理视频 URL
|
|
|
const processVideo = async (url: string): Promise<void> => {
|
|
|
if (!url) return;
|
|
|
@@ -199,6 +205,15 @@ const processVideo = async (url: string): Promise<void> => {
|
|
|
loading.value = true;
|
|
|
error.value = "";
|
|
|
|
|
|
+ // 检查是否为标准的 HLS 流地址
|
|
|
+ if (isStandardHlsUrl(url)) {
|
|
|
+ processedVideoUrl.value = url;
|
|
|
+ await nextTick();
|
|
|
+ await initVideoPlayer();
|
|
|
+ emit("videoLoaded", processedVideoUrl.value);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
let processedUrl = url;
|
|
|
if (processedUrl.includes("cover")) {
|
|
|
processedUrl = processedUrl.replace("cover", "play");
|
|
|
@@ -209,10 +224,7 @@ const processVideo = async (url: string): Promise<void> => {
|
|
|
const decryptedData = await loader(processedUrl);
|
|
|
|
|
|
if (typeof decryptedData === "string") {
|
|
|
- // 处理 M3U8 内容
|
|
|
const playlist = processM3u8Content(decryptedData, processedUrl);
|
|
|
-
|
|
|
- // 创建 Blob URL
|
|
|
const blob = new Blob([playlist], { type: "application/x-mpegURL" });
|
|
|
processedVideoUrl.value = URL.createObjectURL(blob);
|
|
|
} else {
|
|
|
@@ -222,7 +234,7 @@ const processVideo = async (url: string): Promise<void> => {
|
|
|
processedVideoUrl.value = url;
|
|
|
}
|
|
|
|
|
|
- // 初始化播放器
|
|
|
+ await nextTick();
|
|
|
await initVideoPlayer();
|
|
|
emit("videoLoaded", processedVideoUrl.value);
|
|
|
} catch (err) {
|
|
|
@@ -270,14 +282,13 @@ const processM3u8Content = (m3u8Text: string, baseUrl: string): string => {
|
|
|
|
|
|
// 初始化视频播放器
|
|
|
const initVideoPlayer = async (): Promise<void> => {
|
|
|
- if (!videoElement.value || !processedVideoUrl.value) return;
|
|
|
+ if (!videoElement.value || !processedVideoUrl.value) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
const video = videoElement.value;
|
|
|
-
|
|
|
- // 销毁现有的 HLS 实例
|
|
|
destroyHls();
|
|
|
|
|
|
- // 检查浏览器是否原生支持 HLS
|
|
|
if (video.canPlayType("application/vnd.apple.mpegurl")) {
|
|
|
video.src = processedVideoUrl.value;
|
|
|
} else if (Hls.isSupported()) {
|
|
|
@@ -295,7 +306,7 @@ const initVideoPlayer = async (): Promise<void> => {
|
|
|
switch (data.type) {
|
|
|
case Hls.ErrorTypes.NETWORK_ERROR:
|
|
|
if (data.details === "manifestParsingError") {
|
|
|
- error.value = "视频加载失败";
|
|
|
+ error.value = "视频清单解析失败";
|
|
|
hlsInstance.value?.destroy();
|
|
|
hlsInstance.value = null;
|
|
|
video.src = processedVideoUrl.value;
|
|
|
@@ -361,7 +372,7 @@ const onVideoLoadedData = (): void => {};
|
|
|
|
|
|
const onVideoCanPlay = (): void => {
|
|
|
if (props.autoPlay && videoElement.value) {
|
|
|
- videoElement.value.play().catch(console.warn);
|
|
|
+ videoElement.value.play().catch(() => {});
|
|
|
}
|
|
|
};
|
|
|
|