MENU

Typecho 引入 DPlayer 的简单方法

• February 29, 2020 • Read: 366 • 分享

本文转载

LOGI的教程

原文地址
想在文章中插入视频,尝试 iframevideo 标签后发现 m3u8 流会触发下载无法播放,用 hls 该问题后,碰到了 403 forbbiden。联想到前些天新浪图床加 referrer 的解决方法,随手一试竟然可以。后来发现 Mixed ContentCORS 才是大坑,几经了解,这个问题只能靠视频源服务器解决,所以把视频放在自己的服务器或 CDN 是不会有问题的。最后,用 js 封装了一下神器 DPlayer,使用体验良好。

演示效果

此处内容需要评论回复后方可阅读
此处内容需要评论回复后方可阅读
韩愈
天街小雨润如酥,草色遥看近却无。
最是一年春好处,绝胜烟柳满皇都。

引入 JS

对于 本主题,依次进入 控制台 - 外观 - 设置外观 - 主题自定义扩展,将代码加入到 自定义 HTML 元素拓展 - 标签: head 头部 (meta 元素后)。其他主题,加入到主题对应的 header.php 中的 </head> 标签前。

JavaScript Code

<script>
    // DPlayer API
    document.addEventListener('DOMContentLoaded', initDplayer);
    function initDplayer() {
        const common = {
            loadResource: function (id, resource, type, callback) {
                let loaded = document.head.querySelector('#' + id);
                if (loaded) {
                    callback();
                    return;
                }
                const element = document.createElement(type);
                element.onload = element.onreadystatechange = () => {
                    if (!loaded && (!element.readyState || /loaded|complete/.test(element.readyState))) {
                        element.onload = element.onreadystatechange = null;
                        loaded = true;
                        callback();
                    }
                }
                if (type === 'link') {
                    element.rel = 'stylesheet';
                    element.href = resource;
                } else {
                    element.src = resource;
                }
                element.id = id;
                document.getElementsByTagName('head')[0].appendChild(element);
            },
            loadResources: function (callback) {
                const cdn = '//s0.pstatp.com/cdn/expire-1-M';
                const resources = [
                    '/dplayer/1.25.0/DPlayer.min.css',
                    '/dplayer/1.25.0/DPlayer.min.js',
                    '/hls.js/0.12.4/hls.light.min.js',
                    '/flv.js/1.5.0/flv.min.js'
                ];
                let unloadedResourceCount = resources.length;
                resources.forEach(resource => {
                    this.loadResource(btoa(resource).replace(/[=+\/]/g, ''), cdn + resource,
                        ({
                            'css': 'link',
                            'js': 'script'
                        })[resource.split('.').pop()],
                        () => --unloadedResourceCount ? null : callback()
                    );
                });
            },
            createDplayers: function (sources, callback) {
                for (let i = 0; i < sources.length; i++) {
                    const child = document.createElement('div');
                    const src = sources[i].getAttribute('src');
                    sources[i].parentNode.insertBefore(child, sources[i]);
                    sources[i].style.display = 'none';
                    const type = src.split('.').pop();
                    const option = { url: src };
                    type === 'flv' ? option.type = type : null;
                    const dplayer = new DPlayer({ container: child, preload: 'none', autoplay: false, screenshot: false, video: option });
                }
                if (typeof callback === 'function') callback();
            }
        };
        const mirages = {
            isMirages: function () { return Mirages || false },
            fixVideoSize: function (length) {
                let outerTimer = false;
                const outerInterval = setInterval(() => {
                    if (outerTimer) return;
                    const videos = document.getElementsByTagName('video');
                    if (videos.length === length) {
                        const dplayerWraps = document.querySelectorAll('.dplayer-video-wrap');
                        for (let i = 0; i < length; i++) {
                            const videoContainers = dplayerWraps[i].querySelectorAll('.video-container.video-4-3');
                            if (videoContainers.length) {
                                videoContainers[0].style = 'position: initial;';
                                videoContainers[0].className = 'video-container video-16-9';
                                console.log('video-4-3 fixed.');
                            } else {
                                const videoContainer = document.createElement('div');
                                videoContainer.style = 'position: initial;';
                                videoContainer.className = 'video-container video-16-9';
                                videoContainer.appendChild(videos[i]);
                                dplayerWraps[i].appendChild(videoContainer);
                                console.log('video-16-9 inserted.');
                                const targetNode = videoContainer;
                                const config = { childList: true };
                                const callback = (mutationsList, observer) => {
                                    const newVideoContainers = videoContainer.querySelectorAll(
                                        '.video-container.video-4-3');
                                    if (newVideoContainers.length) {
                                        newVideoContainers[0].className = '';
                                        console.log('auto inserted video-4-3 fixed.');
                                        observer.disconnect();
                                    }
                                };
                                const observer = new MutationObserver(callback);
                                observer.observe(targetNode, config);
                                setTimeout(() => observer.disconnect(), 1000 * 120);
                            }
                        }
                        outerTimer = true;
                        clearInterval(outerInterval);
                    }
                }, 500);
            }
        };
        const dps = document.getElementsByTagName('dp');
        if (dps.length !== 0) {
            common.loadResources(() => common.createDplayers(dps, () => {
                // 修正 Mirages 视频比例错误
                mirages.isMirages() ? mirages.fixVideoSize(dps.length) : null;
            }));
        }
    };
</script>

如果你开启了 PJAX,可能需要单独加入回调函数。对于本主题,依次进入 控制台 - 外观 - 设置外观 - PJAX(BETA) - PJAX RELOAD,将 initDplayer(); 添加进入即可。

添加播放器

在文章所需位置以 html 形式插入代码,即可添加播放器,支持 m3u8mp4flvmkv 格式,不过编码必须是 H.264 AAC

!!!
<dp src="demo.mp4"></dp>
!!!


DPlayer

Last Modified: March 23, 2020
Archives QR Code Tip
QR Code for this page
Tipping QR Code
Leave a Comment

2 Comments
  1. 孔乙己 孔乙己   Windows 10 x64 Edition  Google Chrome 80.0.3987.122

    吉良吉影为你点赞

    1. 月下读心 月下读心   iOS 13.3.1  Safari 13.0.5

      @孔乙己人生赢家@(大拇指)

0:00