|
|
|
@ -1,7 +1,6 @@
@@ -1,7 +1,6 @@
|
|
|
|
|
class Owncast { |
|
|
|
|
constructor() { |
|
|
|
|
this.player; |
|
|
|
|
this.streamStatus = null; |
|
|
|
|
|
|
|
|
|
this.websocket = null; |
|
|
|
|
this.configData; |
|
|
|
@ -14,10 +13,10 @@ class Owncast {
@@ -14,10 +13,10 @@ class Owncast {
|
|
|
|
|
this.offlineTimer = null; |
|
|
|
|
this.statusTimer = null; |
|
|
|
|
this.disableChatTimer = null; |
|
|
|
|
this.streamDurationTimer = null; |
|
|
|
|
|
|
|
|
|
// misc
|
|
|
|
|
this.streamIsOnline = false; |
|
|
|
|
this.lastDisconnectTime = null; |
|
|
|
|
this.streamStatus = null; |
|
|
|
|
|
|
|
|
|
Vue.filter('plural', pluralize); |
|
|
|
|
|
|
|
|
@ -36,6 +35,7 @@ class Owncast {
@@ -36,6 +35,7 @@ class Owncast {
|
|
|
|
|
this.handlePlayerPlaying = this.handlePlayerPlaying.bind(this); |
|
|
|
|
this.handlePlayerEnded = this.handlePlayerEnded.bind(this); |
|
|
|
|
this.handlePlayerError = this.handlePlayerError.bind(this); |
|
|
|
|
this.setCurrentStreamDuration = this.setCurrentStreamDuration.bind(this); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
init() { |
|
|
|
@ -45,7 +45,7 @@ class Owncast {
@@ -45,7 +45,7 @@ class Owncast {
|
|
|
|
|
this.vueApp = new Vue({ |
|
|
|
|
el: '#app-container', |
|
|
|
|
data: { |
|
|
|
|
isOnline: false, |
|
|
|
|
playerOn: false, |
|
|
|
|
messages: [], |
|
|
|
|
overallMaxViewerCount: 0, |
|
|
|
|
sessionMaxViewerCount: 0, |
|
|
|
@ -86,7 +86,7 @@ class Owncast {
@@ -86,7 +86,7 @@ class Owncast {
|
|
|
|
|
}); |
|
|
|
|
this.player.init(); |
|
|
|
|
|
|
|
|
|
this.getChatHistory(); |
|
|
|
|
// this.getChatHistory();
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
setConfigData(data) { |
|
|
|
@ -202,7 +202,10 @@ class Owncast {
@@ -202,7 +202,10 @@ class Owncast {
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// handle UI things from stream status result
|
|
|
|
|
updateStreamStatus(status) { |
|
|
|
|
updateStreamStatus(status = {}) { |
|
|
|
|
if (!status) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
// update UI
|
|
|
|
|
this.vueApp.streamStatus = status.online ? MESSAGE_ONLINE : MESSAGE_OFFLINE; |
|
|
|
|
this.vueApp.viewerCount = status.viewerCount; |
|
|
|
@ -211,14 +214,35 @@ class Owncast {
@@ -211,14 +214,35 @@ class Owncast {
|
|
|
|
|
|
|
|
|
|
this.lastDisconnectTime = status.lastDisconnectTime; |
|
|
|
|
|
|
|
|
|
if (status.online && !this.streamIsOnline) { |
|
|
|
|
if (!this.streamStatus) { |
|
|
|
|
// display offline mode the first time we get status, and it's offline.
|
|
|
|
|
if (!status.online) { |
|
|
|
|
this.handleOfflineMode(); |
|
|
|
|
} else { |
|
|
|
|
this.handleOnlineMode(); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if (status.online && !this.streamStatus.online) { |
|
|
|
|
// stream has just come online.
|
|
|
|
|
this.handleOnlineMode(); |
|
|
|
|
} else if (!status.online && !this.streamStatus) { |
|
|
|
|
// stream has just gone offline.
|
|
|
|
|
// display offline mode the first time we get status, and it's offline.
|
|
|
|
|
} else if (!status.online && this.streamStatus.online) { |
|
|
|
|
// stream has just flipped offline.
|
|
|
|
|
this.handleOfflineMode(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// if (status.online && !this.streamIsOnline) {
|
|
|
|
|
|
|
|
|
|
// } else if (!status.online && !this.streamStatus) {
|
|
|
|
|
// this.handleOfflineMode();
|
|
|
|
|
// } else if (!status.online && this.streamIsOnline) {
|
|
|
|
|
// // we've just flipped from online to offline
|
|
|
|
|
// clearInterval(this.streamDurationTimer);
|
|
|
|
|
// this.handleOfflineMode();
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// keep a local copy
|
|
|
|
|
this.streamStatus = status; |
|
|
|
|
|
|
|
|
|
if (status.online) { |
|
|
|
|
// only do this if video is paused, so no unnecessary img fetches
|
|
|
|
@ -226,25 +250,17 @@ class Owncast {
@@ -226,25 +250,17 @@ class Owncast {
|
|
|
|
|
this.player.setPoster(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.streamStatus = status; |
|
|
|
|
this.setCurrentStreamDuration(); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// update vueApp.streamStatus text when online
|
|
|
|
|
setCurrentStreamDuration() { |
|
|
|
|
// If we're offline then don't update any of the UI.
|
|
|
|
|
if (!this.streamStatus.online) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Default to something
|
|
|
|
|
let streamDurationString = "" |
|
|
|
|
let streamDurationString = ''; |
|
|
|
|
|
|
|
|
|
if (this.streamStatus.online && this.streamStatus.lastConnectTime) { |
|
|
|
|
if (this.streamStatus.lastConnectTime) { |
|
|
|
|
const diff = (Date.now() - Date.parse(this.streamStatus.lastConnectTime)) / 1000; |
|
|
|
|
streamDurationString = secondsToHMMSS(diff); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.vueApp.streamStatus = `${MESSAGE_ONLINE} ${streamDurationString}.` |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -253,13 +269,12 @@ class Owncast {
@@ -253,13 +269,12 @@ class Owncast {
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// basically hide video and show underlying "poster"
|
|
|
|
|
// primarily called when video onEnded was called because some video has been buffered to play after stream has gone offline.
|
|
|
|
|
handleOfflineMode() { |
|
|
|
|
this.streamIsOnline = false; |
|
|
|
|
this.vueApp.isOnline = false; |
|
|
|
|
clearInterval(this.streamDurationTimer); |
|
|
|
|
this.vueApp.streamStatus = MESSAGE_OFFLINE; |
|
|
|
|
|
|
|
|
|
if (this.lastDisconnectTime) { |
|
|
|
|
const remainingChatTime = TIMER_DISABLE_CHAT_AFTER_OFFLINE - (Date.now() - new Date(this.lastDisconnectTime)); |
|
|
|
|
if (this.streamStatus) { |
|
|
|
|
const remainingChatTime = TIMER_DISABLE_CHAT_AFTER_OFFLINE - (Date.now() - new Date(this.streamStatus.lastDisconnectTime)); |
|
|
|
|
const countdown = (remainingChatTime < 0) ? 0 : remainingChatTime; |
|
|
|
|
this.disableChatTimer = setTimeout(this.messagingInterface.disableChat, countdown); |
|
|
|
|
} |
|
|
|
@ -267,8 +282,7 @@ class Owncast {
@@ -267,8 +282,7 @@ class Owncast {
|
|
|
|
|
|
|
|
|
|
// play video!
|
|
|
|
|
handleOnlineMode() { |
|
|
|
|
this.streamIsOnline = true; |
|
|
|
|
this.vueApp.isOnline = true; |
|
|
|
|
this.vueApp.playerOn = true; |
|
|
|
|
this.vueApp.streamStatus = MESSAGE_ONLINE; |
|
|
|
|
|
|
|
|
|
this.player.startPlayer(); |
|
|
|
@ -276,7 +290,8 @@ class Owncast {
@@ -276,7 +290,8 @@ class Owncast {
|
|
|
|
|
this.disableChatTimer = null; |
|
|
|
|
this.messagingInterface.enableChat(); |
|
|
|
|
|
|
|
|
|
setInterval(this.setCurrentStreamDuration.bind(this), 1000); |
|
|
|
|
this.streamDurationTimer = |
|
|
|
|
setInterval(this.setCurrentStreamDuration, TIMER_STREAM_DURATION_COUNTER); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// when videojs player is ready, start polling for stream
|
|
|
|
@ -291,20 +306,21 @@ class Owncast {
@@ -291,20 +306,21 @@ class Owncast {
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// likely called some time after stream status has gone offline.
|
|
|
|
|
// disable chat after some time.
|
|
|
|
|
handlePlayerEnded() { |
|
|
|
|
// do something?
|
|
|
|
|
this.handleOfflineMode(); |
|
|
|
|
this.vueApp.playerOn = false; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
handlePlayerError() { |
|
|
|
|
// do something?
|
|
|
|
|
this.handleOfflineMode(); |
|
|
|
|
this.handlePlayerEnded(); |
|
|
|
|
// stop timers?
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
async getChatHistory() { |
|
|
|
|
const url = "/chat"; |
|
|
|
|
const response = await fetch(url); |
|
|
|
|
const response = await fetch(URL_CHAT_HISTORY); |
|
|
|
|
const data = await response.json(); |
|
|
|
|
const messages = data.map(function (message) { |
|
|
|
|
return new Message(message); |
|
|
|
|