Add PeerTube support
This commit is contained in:
parent
3668c1b3da
commit
d516c5ebfc
|
@ -22,6 +22,7 @@ var order = [
|
|||
'rtmp.coffee',
|
||||
'hls.coffee',
|
||||
'twitchclip.coffee',
|
||||
'peertube.coffee',
|
||||
'update.coffee'
|
||||
];
|
||||
|
||||
|
|
113
player/peertube.coffee
Normal file
113
player/peertube.coffee
Normal file
|
@ -0,0 +1,113 @@
|
|||
PEERTUBE_EMBED_WARNING = 'This channel is embedding PeerTube content from %link%.
|
||||
PeerTube instances may use P2P technology that will expose your IP address to third parties, including but not
|
||||
limited to other users in this channel. It is also conceivable that if the content in question is in violation of
|
||||
copyright laws your IP address could be potentially be observed by legal authorities monitoring the tracker of
|
||||
this PeerTube instance. The operators of %site% are not responsible for the data sent by the embedded player to
|
||||
third parties on your behalf.<br><br> If you understand the risks, wish to assume all liability, and continue to
|
||||
the content, click "Embed" below to allow the content to be embedded.<hr>'
|
||||
|
||||
window.PeerPlayer = class PeerPlayer extends Player
|
||||
constructor: (data) ->
|
||||
if not (this instanceof PeerPlayer)
|
||||
return new PeerPlayer(data)
|
||||
|
||||
@warn(data)
|
||||
|
||||
warn: (data) ->
|
||||
site = new URL(document.URL).hostname
|
||||
embedSrc = data.meta.embed.domain
|
||||
link = "<a href=\"http://#{embedSrc}\" target=\"_blank\"><strong>#{embedSrc}</strong></a>"
|
||||
alert = makeAlert('Privacy Advisory', PEERTUBE_EMBED_WARNING.replace('%link%', link).replace('%site%', site),
|
||||
'alert-warning')
|
||||
.removeClass('col-md-12')
|
||||
$('<button/>').addClass('btn btn-default')
|
||||
.text('Embed')
|
||||
.on('click', =>
|
||||
@load(data)
|
||||
)
|
||||
.appendTo(alert.find('.alert'))
|
||||
removeOld(alert)
|
||||
|
||||
load: (data) ->
|
||||
@setMediaProperties(data)
|
||||
|
||||
waitUntilDefined(window, 'PeerTubePlayer', =>
|
||||
video = $('<iframe/>')
|
||||
removeOld(video)
|
||||
video.attr(
|
||||
src: "https://#{data.meta.embed.domain}/videos/embed/#{data.meta.embed.uuid}?api=1"
|
||||
allow: 'autoplay; fullscreen'
|
||||
)
|
||||
|
||||
if USEROPTS.wmode_transparent
|
||||
video.attr('wmode', 'transparent')
|
||||
|
||||
@peertube = new PeerTubePlayer(video[0])
|
||||
|
||||
@peertube.addEventListener('playbackStatusChange', (status) =>
|
||||
@paused = status == 'paused'
|
||||
if CLIENT.leader
|
||||
sendVideoUpdate()
|
||||
)
|
||||
|
||||
@peertube.addEventListener('playbackStatusUpdate', (status) =>
|
||||
@peertube.currentTime = status.position
|
||||
|
||||
if status.playbackState == "ended" and CLIENT.leader
|
||||
socket.emit('playNext')
|
||||
)
|
||||
|
||||
@peertube.addEventListener('volumeChange', (volume) =>
|
||||
VOLUME = volume
|
||||
setOpt("volume", VOLUME)
|
||||
)
|
||||
|
||||
@play()
|
||||
@setVolume(VOLUME)
|
||||
)
|
||||
|
||||
play: ->
|
||||
@paused = false
|
||||
if @peertube and @peertube.ready
|
||||
@peertube.play().catch((error) ->
|
||||
console.error('PeerTube::play():', error)
|
||||
)
|
||||
|
||||
pause: ->
|
||||
@paused = true
|
||||
if @peertube and @peertube.ready
|
||||
@peertube.pause().catch((error) ->
|
||||
console.error('PeerTube::pause():', error)
|
||||
)
|
||||
|
||||
seekTo: (time) ->
|
||||
if @peertube and @peertube.ready
|
||||
@peertube.seek(time)
|
||||
|
||||
getVolume: (cb) ->
|
||||
if @peertube and @peertube.ready
|
||||
@peertube.getVolume().then((volume) ->
|
||||
cb(parseFloat(volume))
|
||||
).catch((error) ->
|
||||
console.error('PeerTube::getVolume():', error)
|
||||
)
|
||||
else
|
||||
cb(VOLUME)
|
||||
|
||||
setVolume: (volume) ->
|
||||
if @peertube and @peertube.ready
|
||||
@peertube.setVolume(volume).catch((error) ->
|
||||
console.error('PeerTube::setVolume():', error)
|
||||
)
|
||||
|
||||
getTime: (cb) ->
|
||||
if @peertube and @peertube.ready
|
||||
cb(@peertube.currentTime)
|
||||
else
|
||||
cb(0)
|
||||
|
||||
setQuality: (quality) ->
|
||||
# USEROPTS.default_quality
|
||||
# @peertube.getResolutions()
|
||||
# @peertube.setResolution(resolutionId : number)
|
||||
|
|
@ -14,6 +14,7 @@ TYPE_MAP =
|
|||
sb: StreamablePlayer
|
||||
tc: TwitchClipPlayer
|
||||
cm: VideoJSPlayer
|
||||
pt: PeerPlayer
|
||||
|
||||
window.loadMediaPlayer = (data) ->
|
||||
try
|
||||
|
|
|
@ -6,6 +6,7 @@ const ffmpeg = require("./ffmpeg");
|
|||
const mediaquery = require("@cytube/mediaquery");
|
||||
const YouTube = require("@cytube/mediaquery/lib/provider/youtube");
|
||||
const Vimeo = require("@cytube/mediaquery/lib/provider/vimeo");
|
||||
const PeerTube = require("@cytube/mediaquery/lib/provider/peertube");
|
||||
const Streamable = require("@cytube/mediaquery/lib/provider/streamable");
|
||||
const TwitchVOD = require("@cytube/mediaquery/lib/provider/twitch-vod");
|
||||
const TwitchClip = require("@cytube/mediaquery/lib/provider/twitch-clip");
|
||||
|
@ -366,6 +367,16 @@ var Getters = {
|
|||
});
|
||||
},
|
||||
|
||||
/* PeerTube network */
|
||||
pt: function (id, callback) {
|
||||
PeerTube.lookup(id).then(video => {
|
||||
video = new Media(video.id, video.title, video.duration, "pt", video.meta);
|
||||
callback(null, video);
|
||||
}).catch(error => {
|
||||
callback(error.message || error);
|
||||
});
|
||||
},
|
||||
|
||||
/* custom media - https://github.com/calzoneman/sync/issues/655 */
|
||||
cm: async function (id, callback) {
|
||||
try {
|
||||
|
|
|
@ -205,6 +205,9 @@
|
|||
return "https://clips.twitch.tv/" + id;
|
||||
case "cm":
|
||||
return id;
|
||||
case "pt":
|
||||
const [domain,uuid] = id.split(';');
|
||||
return `https://${domain}/videos/watch/${uuid}`;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -252,6 +252,7 @@ html(lang="en")
|
|||
script(defer, src="https://www.youtube.com/iframe_api")
|
||||
script(defer, src="https://api.dmcdn.net/all.js")
|
||||
script(defer, src="https://player.vimeo.com/api/player.js")
|
||||
script(defer, src="/js/peertube.js")
|
||||
script(defer, src="/js/sc.js")
|
||||
script(defer, src="/js/video.js")
|
||||
script(defer, src="/js/videojs-contrib-hls.min.js")
|
||||
|
|
1
www/js/peertube.js
Normal file
1
www/js/peertube.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -52,6 +52,12 @@ function formatURL(data) {
|
|||
return data.id;
|
||||
case "cu":
|
||||
return data.meta.embed.src;
|
||||
case "pt":
|
||||
if(data.meta.embed.onlyLong){
|
||||
return `https://${data.meta.embed.domain}/videos/watch/${data.meta.embed.uuid}`;
|
||||
} else {
|
||||
return `https://${data.meta.embed.domain}/w/${data.meta.embed.short}`;
|
||||
}
|
||||
default:
|
||||
return "#";
|
||||
}
|
||||
|
@ -1385,6 +1391,19 @@ function parseMediaLink(url) {
|
|||
}
|
||||
}
|
||||
|
||||
/* PeerTubes */
|
||||
if(data.pathname.match('^/w/|^/videos/watch/')){
|
||||
const regLong = [8, 4, 4, 4, 12].map(x => `[0-9a-f]{${x}}`).join('-');
|
||||
const regShort = '[a-zA-Z0-9]{22}';
|
||||
const pattern = new RegExp(`(?:/w/|/videos/watch/)(?:(?<short>${regShort})|(?<long>${regLong}))`);
|
||||
if((m = data.pathname.match(pattern))) {
|
||||
return {
|
||||
id: `${data.hostname};${m.groups.short || m.groups.long}`,
|
||||
type: "pt"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/* Raw file (server will check) */
|
||||
if (data.protocol.match(/^http/)) {
|
||||
return {
|
||||
|
|
Loading…
Reference in a new issue