Greasy Fork

Greasy Fork is available in English.

.M3U8 HLS Player

Lets you play .m3u8 with hls player.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        .M3U8 HLS Player
// @namespace   http://greasyfork.icu/zh-CN/users/7232-andy-wong
// @description Lets you play .m3u8 with hls player.
// @include     *://*
// @version     2.0
// @require     https://cdn.jsdelivr.net/npm/hls.js@latest
// @grant       none
// @run-at      document-start
// ==/UserScript==

/* makes use of DailyMotion's MSE-based HLS client:
   https://github.com/dailymotion/hls.js */

var hlsJsUrl = "https://cdn.jsdelivr.net/npm/hls.js@latest";
var script = document.createElement('script');
script.onload = function() {
    window.postMessage({ type: "HLS_READY", isSupported: Hls.isSupported() }, "*");
};
script.src = hlsJsUrl;
document.head.appendChild(script);

function loadVideo(video) {
    var hls = new Hls();
    hls.loadSource(video.src);
    hls.attachMedia(video);
    hls.on(Hls.Events.MANIFEST_PARSED, function() {
        video.play();
    });
}

window.addEventListener("message", function(event) {
    if (event.source !== window)
        return;

    if (event.data.type && (event.data.type === "START_HLS_PLAYBACK")) {
        loadVideo(document.querySelector("video[inline-hls-player---video=" + event.data.videoId + "]"));
    }
}, false);

var hlsJsState = 0;
var hlsJsReadyCallbacks = [];


function loadHlsJs(callback) {
    if (hlsJsState === 0) {
        hlsJsState = 1;
    }

    if (hlsJsState === 1) {
        hlsJsReadyCallbacks.push(callback);
    }
}

function onHlsReady(isSupported) {
    hlsJsState = isSupported ? 2 : -1;
    hlsJsReadyCallbacks.forEach(callback => callback());
}

function getVideoId() {
    Array(24).fill().map(el => String.fromCharCode(Math.random() * 26 + 97));
}

function onVideoError(video) {
    if (hlsJsState === 0) {
        loadHlsJs(function() { onVideoError(video) });
    } else if (hlsJsState === 2) {
        let videoId = video.getAttribute("inline-hls-player---video");
        if (!videoId) {
            videoId = getVideoId();
            video.setAttribute("inline-hls-player---video", videoId);
        }

        window.postMessage({ type: "START_HLS_PLAYBACK", videoId: videoId }, "*");
    }
}

function isUnsupportedHlsVideo(element) {
    return (element instanceof HTMLVideoElement) &&
        element.error &&
        element.error.code === 4 &&
        element.src &&
        element.src.match(/\.m3u8($|\?)/);
}

function onWindowError(event) {
    const target = event.target;
    if (isUnsupportedHlsVideo(target)) {
        event.preventDefault();
        event.stopImmediatePropagation();
        onVideoError(target);
    }
}

document.addEventListener("error", onWindowError, true);

const videos = document.querySelectorAll("video");
if (videos.length) {
    for (var i = 0; i < videos.length; i++) {
        if (isUnsupportedHlsVideo(videos[i])) {
            onVideoError(videos[i]);
        }
    }
}

window.addEventListener("message", function(event) {
    if (event.source !== window)
        return;

    if (event.data.type && (event.data.type === "HLS_READY")) {
        onHlsReady(event.data.isSupported);
    }
}, false);