embyLaunchPotplayer

try to take over the world!

As of 2020-12-20. See the latest version.

// ==UserScript==
// @name         embyLaunchPotplayer
// @name:en      embyLaunchPotplayer
// @name:zh      embyLaunchPotplayer
// @name:zh-CN   embyLaunchPotplayer
// @namespace    http://tampermonkey.net/
// @version      0.8
// @description  try to take over the world!
// @description:zh-cn emby调用外部播放器
// @author       @bpking
// @include       *emby*
// @include       *:8*
// ==/UserScript==
const domain = window.location.href;
const api_key = "?api_key=1b52b02396894aa5a162233f0ef61681";
const reg = /\/[a-z]{2,}\/\S*?id=/;
const regResult = domain.match(reg)[0];

var timer = setInterval(function() {
    var potplayer = document.querySelectorAll("div[is='emby-scroller']:not(.hide) .potplayer")[0];
    if(!potplayer){
        var mainDetailButtons = document.querySelectorAll("div[is='emby-scroller']:not(.hide) .mainDetailButtons")[0];
        if(mainDetailButtons){
              var html = mainDetailButtons.innerHTML;
              mainDetailButtons.innerHTML = html
                  +'<button id="potPlayer" type="button" class="detailButton  emby-button potplayer" title="Potplayer"> <div class="detailButton-content"> <i class="md-icon detailButton-icon"></i>  <div class="detailButton-text">PotPlayer</div> </div> </button>'
                  +'<button id="playNext" type="button" class="detailButton  emby-button playNext" title="稍后播放"> <div class="detailButton-content"> <i class="md-icon detailButton-icon"></i>  <div class="detailButton-text">稍后播放</div> </div> </button>'
                  +'<button id="iina" type="button" class="detailButton  emby-button iina" title="IINA"> <div class="detailButton-content"> <i class="md-icon detailButton-icon"></i>  <div class="detailButton-text">IINA</div> </div> </button>';

            document.querySelector("div[is='emby-scroller']:not(.hide) #potPlayer").onclick = potPlayer;
            document.querySelector("div[is='emby-scroller']:not(.hide) #playNext").onclick = playNext;
            document.querySelector('#iina').onclick = iina;
        }
    }
}, 1000)

function getItemInfo(){
    let domain = window.location.href;
    const itemInfoUrl = domain.replace(regResult, "/emby/Items/").split('&')[0] + "/PlaybackInfo" + api_key;
    console.log("itemInfo:" + itemInfoUrl);
    return new Promise((resolve, reject) => {
        fetch(itemInfoUrl).then(resp =>
          resp.json().then(data => resolve(data)).catch(e => {alert("网络错误,检查api_key是否设置正确  "+e.message)})
    )
  })
}

function getSeek(){
    const resumeButton = document.querySelector("div[is='emby-scroller']:not(.hide) div.resumeButtonText");
    let seek = '';
    if (resumeButton) {
        if (resumeButton.innerText.includes('恢复播放于')) {
            seek = resumeButton.innerText.replace('恢复播放于', '');
        }
    }
    return seek;
}

function getSubUrl(itemInfo, MediaSourceIndex){
    var selectSubtitles = document.querySelector("div[is='emby-scroller']:not(.hide) select.selectSubtitles");
    let subTitleUrl = '';
    if (selectSubtitles) {
        if (selectSubtitles.value > 0) {
            console.log(selectSubtitles.value);
            if (itemInfo.MediaSources[MediaSourceIndex].MediaStreams[selectSubtitles.value].IsExternal) {
                let domain = window.location.href;
                const subtitleCodec = itemInfo.MediaSources[MediaSourceIndex].MediaStreams[selectSubtitles.value].Codec;
                subTitleUrl = domain.replace(regResult, "/emby/videos/").split('&')[0]
                    + "/" + itemInfo.MediaSources[MediaSourceIndex].Id + "/Subtitles/" + selectSubtitles.value + "/"
                    + MediaSourceIndex + "/Stream." + subtitleCodec + api_key;
                console.log(subTitleUrl);
            }
        }
    }
    return subTitleUrl;
}


var getVideoUrl = async function () {
    var selectSource = document.querySelector("div[is='emby-scroller']:not(.hide) select.selectSource");
    var selectAudio = document.querySelector("div[is='emby-scroller']:not(.hide) select.selectAudio");

    const itemInfo = await getItemInfo();
    let MediaSourceIndex = 0;
    for(let i = 0; i< itemInfo.MediaSources.length; i++){
        if(itemInfo.MediaSources[i].Id == selectSource.value){
            MediaSourceIndex = i;
        };
    }
    const container = itemInfo.MediaSources[MediaSourceIndex].Container;
    const MediaSourceId = selectSource.value;
    const PlaySessionId = itemInfo.PlaySessionId;

    const subUrl = await getSubUrl(itemInfo, MediaSourceIndex);

    let domain = window.location.href;
    const streamUrl = domain.replace(regResult, "/emby/videos/").split('&')[0]
        + "/stream." + container + api_key + "&Static=true" + "&MediaSourceId=" + MediaSourceId
        + "&PlaySessionId=" + PlaySessionId;
    return new Array(streamUrl, subUrl);
}


 function potPlayer(){
    const seek = getSeek();
    getVideoUrl().then((videoUrl) => {
        console.log("videoUrl :"+videoUrl);
        const poturl = "potplayer://"+ encodeURI(videoUrl[0]) + " /sub=" + encodeURI(videoUrl[1])+" /current" + " /seek=" + seek;
        console.log("potUrl= " + poturl);
        window.open(poturl, "_blank");
    });
}

//稍后播放,添加至potPlayer播放列表
 function playNext(){
    const seek = getSeek();
    getVideoUrl().then((videoUrl) => {
        console.log("videoUrl :"+videoUrl);
        const poturl = "potplayer://"+ encodeURI(videoUrl[0]) + " /sub=" + encodeURI(videoUrl[1])+" /current /add" + " /seek=" + seek;
        console.log("potUrl= " + poturl);
        window.open(poturl, "_blank");
    });
}

function iina(){
    const seek = getSeek();
    getVideoUrl().then((videoUrl) => {
        console.log("videoUrl :"+videoUrl);
        var iinaurl = "iina://weblink?url=" +escape(videoUrl[0])+"&new_window=1";
        console.log("iinaUrl= " + iinaurl);
        window.open(iinaurl, "_blank");
    });
}