WINDOWS网页Emby调用本地PotPlayer播放器小插件

[复制链接]
查看433 | 回复0 | 2024-2-21 09:47:07 | 显示全部楼层 |阅读模式

登录网站,浏览更多精彩内容

您需要 登录 才可以下载或查看,没有账号?加入我们

×
emby的windows客户端不是特别好用,而且还要买会员。KODI又太过臃肿
就google了一下调用第三方播放器,网上有一个油猴脚本不过需要设置API
设置麻烦而且不一定有权限,也不可能针对每个服务器进行设置
所以在其基础上改造一下用token来调用
地址如下
https://gitee.com/sonata1/emby2potplayer/raw/master/emby2Potplayer
备份脚本:
  1. // ==UserScript==
  2. // @name         emby2Potplayer
  3. // @namespace    http://tampermonkey.net/
  4. // @version      0.1
  5. // @description:zh-cn emby调用potplayer
  6. // @author       @tanxp
  7. // @include       *emby*
  8. // @include       *:8*
  9. // @run-at      document-start
  10. // @grant       unsafeWindow
  11. // @require      https://cdn.bootcdn.net/ajax/libs/jquery-url-parser/2.3.1/purl.js
  12. // ==/UserScript==

  13. //脚本会拦截所有播放请求并拉起potplayer,如需web播放请禁用

  14. function timeFilter (seconds) {
  15.         var ss = parseInt(seconds)/10000000
  16.         var mm = 0// 分
  17.         var hh = 0// 小时
  18.         if (ss > 60) {
  19.           mm = parseInt(ss / 60)
  20.           ss = parseInt(ss % 60)
  21.         }
  22.         if (mm > 60) {
  23.           hh = parseInt(mm / 60)
  24.           mm = parseInt(mm % 60)
  25.         }
  26.         var result = ('00' + parseInt(ss)).slice(-2)
  27.         if (mm > 0) {
  28.           result = ('00' + parseInt(mm)).slice(-2) + ':' + result
  29.         } else {
  30.           result = '00:' + result
  31.         }
  32.         if (hh > 0) {
  33.           result = ('00' + parseInt(hh)).slice(-2) + ':' + result
  34.         }

  35.         return result
  36. };


  37. const originFetch = fetch;
  38. unsafeWindow.fetch = (...arg) => {

  39.     if (arg[0].indexOf('/PlaybackInfo?UserId') > -1 && arg[0].indexOf('IsPlayback=true') > -1) {

  40.         embyPot(arg[0])
  41.         return ''
  42.         }
  43.      else{
  44.          return originFetch(...arg);
  45.      }

  46. }





  47. async function getItemInfo(itemInfoUrl){

  48.     let response = await fetch(itemInfoUrl);
  49.     if(response.ok)
  50.     {
  51.         return await response.json();
  52.     }else{
  53.         throw new Error(response.statusText);
  54.     }
  55. }

  56. function getSeek(itemInfoUrl){
  57.     var seek = ""
  58.     if (itemInfoUrl.indexOf('StartTimeTicks') > -1){
  59.        var StartTimeTicks = purl(itemInfoUrl).param('StartTimeTicks');
  60.         if (StartTimeTicks != '0'){
  61.             seek = timeFilter (StartTimeTicks)
  62.         }
  63.     }
  64.     console.log(seek);

  65.     return seek;
  66. }

  67. function getSubUrl(api_key,itemInfo, MediaSourceIndex){
  68.     var player_id = purl(itemInfoUrl).attr('path').split("/")[3];
  69.     if(player_id == 'PlaybackInfo'){
  70.         player_id = purl(itemInfoUrl).attr('path').split("/")[2];
  71.     }
  72.     if(player_id == 'Items'){
  73.         player_id = purl(itemInfoUrl).attr('path').split("/")[4];
  74.     }
  75.     var play_host = window.location.host
  76.     let selectSubtitles = document.querySelector("div[is='emby-scroller']:not(.hide) select.selectSubtitles");
  77.     let subTitleUrl = '';
  78.     if (selectSubtitles) {
  79.         if (selectSubtitles.value > 0) {
  80.             if (itemInfo.MediaSources[MediaSourceIndex].MediaStreams[selectSubtitles.value].IsExternal) {
  81.                 let subtitleCodec = itemInfo.MediaSources[MediaSourceIndex].MediaStreams[selectSubtitles.value].Codec;
  82.                 let MediaSourceId = itemInfo.MediaSources[MediaSourceIndex].Id;
  83.                 let domain = play_host+'/emby/videos/'+player_id;
  84.                 subTitleUrl = `${domain}/${MediaSourceId}/Subtitles/${selectSubtitles.value}/${MediaSourceIndex}/Stream.${subtitleCodec}?X-Emby-Token=${api_key}`;
  85.                 console.log(subTitleUrl);
  86.             }
  87.         }
  88.     }
  89.     return subTitleUrl;
  90. }


  91. async function getEmbyMediaUrl(itemInfoUrl) {
  92.     var player_id = purl(itemInfoUrl).attr('path').split("/")[3];
  93.     var play_host = window.location.host
  94.     var subUrl = "";
  95.     var api_key = purl(itemInfoUrl).param('X-Emby-Token');
  96.     console.log(itemInfoUrl);



  97.     let itemInfo = await getItemInfo(itemInfoUrl);

  98.     let MediaSourceIndex = 0;
  99.     let MediaSourceId = itemInfo.MediaSources[0].Id
  100.     if (itemInfoUrl.indexOf('MediaSourceId') > -1){
  101.         MediaSourceId = purl(itemInfoUrl).param('MediaSourceId');
  102.         for(let i = 0; i< itemInfo.MediaSources.length; i++){
  103.             if(itemInfo.MediaSources[i].Id == MediaSourceId){
  104.                 MediaSourceIndex = i;
  105.             };
  106.         }
  107.     }

  108.     let container = itemInfo['MediaSources'][MediaSourceIndex]['Container'];
  109.     let PlaySessionId = itemInfo.PlaySessionId;
  110.     let domain = purl(itemInfoUrl).attr('protocol')+'://'+play_host+'/emby/videos/'+player_id;

  111.     if (itemInfoUrl.indexOf('SubtitleStreamIndex') > -1){
  112.         var SubtitleStreamIndex = purl(itemInfoUrl).param('SubtitleStreamIndex')

  113.         if (itemInfo.MediaSources[MediaSourceIndex].MediaStreams[parseInt(SubtitleStreamIndex)].IsExternal) {

  114.             let subtitleCodec = itemInfo.MediaSources[MediaSourceIndex].MediaStreams[parseInt(SubtitleStreamIndex)].Codec;
  115.             let MediaSourceId = itemInfo.MediaSources[MediaSourceIndex].Id;
  116.             let domain = purl(itemInfoUrl).attr('protocol')+'://'+ play_host+'/emby/videos/'+player_id;
  117.             subUrl = `${domain}/${MediaSourceId}/Subtitles/${parseInt(SubtitleStreamIndex)}/${MediaSourceIndex}/Stream.${subtitleCodec}?X-Emby-Token=${api_key}`;
  118.         }
  119.     }
  120.     let streamUrl = `${domain}/stream.${container}?X-Emby-Token=${api_key}&Static=true&MediaSourceId=${MediaSourceId}&PlaySessionId=${PlaySessionId}`;
  121.     return Array(streamUrl, subUrl);
  122. }

  123. async function embyPot(itemInfoUrl) {
  124.     let mediaUrl = await getEmbyMediaUrl(itemInfoUrl);
  125.     let poturl = `potplayer://${encodeURI(mediaUrl[0])} /sub=${encodeURI(mediaUrl[1])} /current /seek=${getSeek(itemInfoUrl)}`;
  126.     console.log(poturl);
  127.     window.open(poturl, "_blank");
  128. }
复制代码

脚本会拦截所有播放请求并拉起potplayer
本脚本监听所有包含emby路径网址和8开头的端口,如有需要请自行改下监听端口
发现播放请求自拉起potplayer,兼容内置和外挂字幕



-------------油猴插件安装---------------
1 什么是油猴插件
脚本,正式的叫法是用户脚本(user script)。
Tampermonkey(油猴),是一款基于浏览器的扩展插件,经过全球各地无数开发者数年的积累,目前已经拥有大量现成优秀脚本,让浏览器实现了一些软件都做不到的逆天功能。
之所以叫做油猴,是因为第一个制作这个浏览器扩展的作者 Aaron Boodman 起名叫做 Greasymonkey,中文直译就是油腻的猴子;后面其他脚本开发的时候,基本都在沿用 Greasymonkey 的一些基本规范,这些脚本也就统称为油猴脚本了。
2 如何安装油猴脚本
油猴插件是一款免费实用且强悍的浏览器插件,支持FireFox/Chrome/Edge/ Opera等浏览器。推荐使用谷歌Chrome浏览器。
插件安装
下面我们来进行安装
演示浏览器:Microsoft Edge(推荐)
方法一
①直接百度手动搜索进入Tampermonkey官网
https://www.tampermonkey.net/
20240221_093140_000.jpg
Tampermonkey Stable为正式版,Tampermonkey Beta为测试版
点击下载,页面跳转至Edge外接扩展商店的安装页面,我们直接获取安装就好了,如下图。
1.webp.jpg
Edge以外的其他浏览器点击下载则会跳转至chrome 网上应用店,正常情况下我们是打不开的,需要科学上网才可以打开。
②或者,很多浏览器里也贴心的自带有相应的扩展市场,我们也可以直接在其扩展应用市场之类的地方直接安装。自己可以尝试!
1.png
2.png
然后把上面的脚本直接全部复制到这个里面保存,记住这个默认的全部清理掉再黏贴就可以了!
这时候重启浏览器,打开emby的网址点播放电影就可以自动拉起PotPlayer播放器播放电影了!
20240221094410.jpg
中国领先的数字技术资源交流中心!

213

主题

39

回帖

3738

积分

达人

积分
3738
学费
3193