Use child iframe for BitChute
By using an iframe we can take advantage of the referrer meta tag, while still being able to scaffold everything relatively easily because it's same-origin
This commit is contained in:
parent
6a0119fa17
commit
8dde08ac6d
|
@ -23,6 +23,7 @@ var order = [
|
||||||
'hls.coffee',
|
'hls.coffee',
|
||||||
'twitchclip.coffee',
|
'twitchclip.coffee',
|
||||||
'peertube.coffee',
|
'peertube.coffee',
|
||||||
|
'bitchute.coffee',
|
||||||
'update.coffee'
|
'update.coffee'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
92
player/bitchute.coffee
Normal file
92
player/bitchute.coffee
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
window.BitChutePlayer = class BitChutePlayer extends Player
|
||||||
|
constructor: (data) ->
|
||||||
|
if not (this instanceof BitChutePlayer)
|
||||||
|
return new BitChutePlayer(data)
|
||||||
|
|
||||||
|
@load(data)
|
||||||
|
|
||||||
|
load: (data) ->
|
||||||
|
@setMediaProperties(data)
|
||||||
|
@ready = false
|
||||||
|
|
||||||
|
waitUntilDefined(window, 'playerjs', =>
|
||||||
|
iframe = $('<iframe/>')
|
||||||
|
.attr(
|
||||||
|
src: '/iframe'
|
||||||
|
allow: 'autoplay; fullscreen'
|
||||||
|
)
|
||||||
|
|
||||||
|
removeOld(iframe)
|
||||||
|
@setupframe(iframe[0], data)
|
||||||
|
|
||||||
|
@player = new playerjs.Player(iframe[0])
|
||||||
|
@player.on('ready', =>
|
||||||
|
@player.on('error', (error) =>
|
||||||
|
console.error('PlayerJS error', error.stack)
|
||||||
|
)
|
||||||
|
@player.on('ended', ->
|
||||||
|
# Streamable seems to not implement this since it loops
|
||||||
|
# gotta use the timeupdate hack below
|
||||||
|
if CLIENT.leader
|
||||||
|
socket.emit('playNext')
|
||||||
|
)
|
||||||
|
@player.on('play', ->
|
||||||
|
@paused = false
|
||||||
|
if CLIENT.leader
|
||||||
|
sendVideoUpdate()
|
||||||
|
)
|
||||||
|
@player.on('pause', ->
|
||||||
|
@paused = true
|
||||||
|
if CLIENT.leader
|
||||||
|
sendVideoUpdate()
|
||||||
|
)
|
||||||
|
|
||||||
|
@player.setVolume(VOLUME * 100)
|
||||||
|
|
||||||
|
if not @paused
|
||||||
|
@player.play()
|
||||||
|
|
||||||
|
@ready = true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
setupframe: (iframe, data) ->
|
||||||
|
iframe.addEventListener('load', =>
|
||||||
|
iframe.contentWindow.VOLUME = VOLUME;
|
||||||
|
iframe.contentWindow.loadMediaPlayer(Object.assign({}, data, { type: 'cm' } ))
|
||||||
|
iframe.contentWindow.document.querySelector('#ytapiplayer').classList.add('vjs-fluid')
|
||||||
|
adapter = iframe.contentWindow.playerjs.VideoJSAdapter(iframe.contentWindow.PLAYER.player)
|
||||||
|
adapter.ready()
|
||||||
|
)
|
||||||
|
|
||||||
|
play: ->
|
||||||
|
@paused = false
|
||||||
|
if @player and @ready
|
||||||
|
@player.play()
|
||||||
|
|
||||||
|
pause: ->
|
||||||
|
@paused = true
|
||||||
|
if @player and @ready
|
||||||
|
@player.pause()
|
||||||
|
|
||||||
|
seekTo: (time) ->
|
||||||
|
if @player and @ready
|
||||||
|
@player.setCurrentTime(time)
|
||||||
|
|
||||||
|
setVolume: (volume) ->
|
||||||
|
if @player and @ready
|
||||||
|
@player.setVolume(volume * 100)
|
||||||
|
|
||||||
|
getTime: (cb) ->
|
||||||
|
if @player and @ready
|
||||||
|
@player.getCurrentTime(cb)
|
||||||
|
else
|
||||||
|
cb(0)
|
||||||
|
|
||||||
|
getVolume: (cb) ->
|
||||||
|
if @player and @ready
|
||||||
|
@player.getVolume((volume) ->
|
||||||
|
cb(volume / 100)
|
||||||
|
)
|
||||||
|
else
|
||||||
|
cb(VOLUME)
|
|
@ -14,7 +14,7 @@ TYPE_MAP =
|
||||||
sb: StreamablePlayer
|
sb: StreamablePlayer
|
||||||
tc: TwitchClipPlayer
|
tc: TwitchClipPlayer
|
||||||
cm: VideoJSPlayer
|
cm: VideoJSPlayer
|
||||||
bc: VideoJSPlayer
|
bc: BitChutePlayer
|
||||||
pt: PeerPlayer
|
pt: PeerPlayer
|
||||||
|
|
||||||
window.loadMediaPlayer = (data) ->
|
window.loadMediaPlayer = (data) ->
|
||||||
|
|
7
src/web/routes/iframe.js
Normal file
7
src/web/routes/iframe.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { sendPug } from '../pug';
|
||||||
|
|
||||||
|
export default function initialize(app) {
|
||||||
|
app.get('/iframe', (req, res) => {
|
||||||
|
return sendPug(res, 'iframe');
|
||||||
|
});
|
||||||
|
}
|
|
@ -212,6 +212,7 @@ module.exports = {
|
||||||
require('./acp').init(app, ioConfig);
|
require('./acp').init(app, ioConfig);
|
||||||
require('../google2vtt').attach(app);
|
require('../google2vtt').attach(app);
|
||||||
require('./routes/google_drive_userscript')(app);
|
require('./routes/google_drive_userscript')(app);
|
||||||
|
require('./routes/iframe')(app);
|
||||||
|
|
||||||
app.use(serveStatic(path.join(__dirname, '..', '..', 'www'), {
|
app.use(serveStatic(path.join(__dirname, '..', '..', 'www'), {
|
||||||
maxAge: webConfig.getCacheTTL()
|
maxAge: webConfig.getCacheTTL()
|
||||||
|
|
36
templates/iframe.pug
Normal file
36
templates/iframe.pug
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
doctype html
|
||||||
|
html(lang="en")
|
||||||
|
head
|
||||||
|
meta(charset="utf-8")
|
||||||
|
meta(name="viewport", content="width=device-width, initial-scale=1.0")
|
||||||
|
meta(name="referrer", content="same-origin")
|
||||||
|
link(rel="stylesheet", href="/css/video-js.css")
|
||||||
|
link(rel="stylesheet", href="/css/videojs-resolution-switcher.css")
|
||||||
|
style.
|
||||||
|
body { overflow-y: hidden }
|
||||||
|
body
|
||||||
|
#wrap
|
||||||
|
#videowrap
|
||||||
|
#ytapiplayer
|
||||||
|
script.
|
||||||
|
const USEROPTS = {
|
||||||
|
default_quality: 'auto'
|
||||||
|
}
|
||||||
|
const CLIENT = {
|
||||||
|
leader: false
|
||||||
|
}
|
||||||
|
let VOLUME = 0;
|
||||||
|
function waitUntilDefined(obj, key, fn) {
|
||||||
|
if(typeof obj[key] === "undefined") {
|
||||||
|
setTimeout(function () {
|
||||||
|
waitUntilDefined(obj, key, fn);
|
||||||
|
}, 100);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fn();
|
||||||
|
}
|
||||||
|
script(src="/js/jquery-1.12.4.min.js")
|
||||||
|
script(src="/js/video.js")
|
||||||
|
script(src="/js/videojs-resolution-switcher.js")
|
||||||
|
script(src="/js/playerjs-0.0.12.js")
|
||||||
|
script(src="/js/player.js")
|
Loading…
Reference in a new issue