const TIME _FRAME _UTC = 1 ;
const TIME _FRAME _BUS = 2 ;
const TIME _FRAME _AGO = 3 ;
var globalLoadedVideoPlayer = false ;
var globalVideoTimeReference = TIME _FRAME _AGO ;
window . addEventListener ( "DOMContentLoaded" , async ( event ) => {
commonPageSetup ( ) ;
const timeSettingsForm = document . getElementById ( "stream-time-settings" ) ;
timeSettingsForm . addEventListener ( "submit" , ( event ) => {
event . preventDefault ( ) ;
updateTimeSettings ( ) ;
} ) ;
await loadDefaults ( ) ;
updateTimeSettings ( ) ;
} ) ;
async function loadDefaults ( ) {
const defaultDataResponse = await fetch ( "/thrimshim/defaults" ) ;
if ( ! defaultDataResponse . ok ) {
addError (
"Failed to load Thrimbletrimmer data. This probably means that everything is broken (or, possibly, just that the Wubloader host is down). Please sound the alarm."
) ;
return ;
}
const defaultData = await defaultDataResponse . json ( ) ;
const streamNameField = document . getElementById ( "stream-time-setting-stream" ) ;
streamNameField . value = defaultData . video _channel ;
globalBusStartTime = new Date ( defaultData . bustime _start ) ;
}
// Gets the start time of the video from settings. Returns an invalid date object if the user entered bad data.
function getStartTime ( ) {
switch ( globalVideoTimeReference ) {
case 1 :
return dateObjFromWubloaderTime ( globalStartTimeString ) ;
case 2 :
return dateObjFromBusTime ( globalStartTimeString ) ;
case 3 :
return new Date (
new Date ( ) . getTime ( ) - 1000 * parseInputTimeAsNumberOfSeconds ( globalStartTimeString )
) ;
}
}
// Gets the end time of the video from settings. Returns null if there's no end time. Returns an invalid date object if the user entered bad data.
function getEndTime ( ) {
if ( globalEndTimeString === "" ) {
return null ;
}
switch ( globalVideoTimeReference ) {
case 1 :
return dateObjFromWubloaderTime ( globalEndTimeString ) ;
case 2 :
return dateObjFromBusTime ( globalEndTimeString ) ;
case 3 :
return new Date (
new Date ( ) . getTime ( ) - 1000 * parseInputTimeAsNumberOfSeconds ( globalEndTimeString )
) ;
}
}
function parseInputTimeAsNumberOfSeconds ( inputTime ) {
// We need to handle inputs like "-0:10:15" in a way that consistently makes the time negative.
// Since we can't assign the negative sign to any particular part, we'll check for the whole thing here.
let direction = 1 ;
if ( inputTime . startsWith ( "-" ) ) {
inputTime = inputTime . slice ( 1 ) ;
direction = - 1 ;
}
const parts = inputTime . split ( ":" , 3 ) ;
return ( parseInt ( parts [ 0 ] ) + ( parts [ 1 ] || 0 ) / 60 + ( parts [ 2 ] || 0 ) / 3600 ) * 60 * 60 * direction ;
}
function updateTimeSettings ( ) {
updateStoredTimeSettings ( ) ;
if ( globalLoadedVideoPlayer ) {
updateSegmentPlaylist ( ) ;
} else {
loadVideoPlayerFromDefaultPlaylist ( ) ;
globalLoadedVideoPlayer = true ;
}
updateDownloadLink ( ) ;
const startTime = getStartTime ( ) ;
const endTime = getEndTime ( ) ;
if ( endTime && endTime < startTime ) {
addError (
"End time is before the start time. This will prevent video loading and cause other problems."
) ;
}
}
function generateDownloadURL ( startTime , endTime , downloadType , allowHoles , quality ) {
const startURLTime = wubloaderTimeFromDateObj ( startTime ) ;
const endURLTime = wubloaderTimeFromDateObj ( endTime ) ;
const queryParts = [ ` type= ${ downloadType } ` , ` allow_holes= ${ allowHoles } ` ] ;
if ( startURLTime ) {
queryParts . push ( ` start= ${ startURLTime } ` ) ;
}
if ( endURLTime ) {
queryParts . push ( ` end= ${ endURLTime } ` ) ;
}
const downloadURL = ` /cut/ ${ globalStreamName } / ${ quality } .ts? ${ queryParts . join ( "&" ) } ` ;
return downloadURL ;
}
function updateDownloadLink ( ) {
const downloadLink = document . getElementById ( "download" ) ;
const downloadURL = generateDownloadURL ( getStartTime ( ) , getEndTime ( ) , "rough" , true , "source" ) ;
downloadLink . href = downloadURL ;
}
function updateStoredTimeSettings ( ) {
globalStreamName = document . getElementById ( "stream-time-setting-stream" ) . value ;
globalStartTimeString = document . getElementById ( "stream-time-setting-start" ) . value ;
globalEndTimeString = document . getElementById ( "stream-time-setting-end" ) . value ;
const radioSelection = document . querySelectorAll ( "#stream-time-frame-of-reference > input" ) ;
for ( radioItem of radioSelection ) {
if ( radioItem . checked ) {
globalVideoTimeReference = + radioItem . value ;
break ;
}
}
}