various fixes

This commit is contained in:
Thomas Zarebczan 2022-03-15 22:45:16 -04:00 committed by Thomas Zarebczan
parent 05b44fc4ab
commit 60c317dedf
5 changed files with 45 additions and 18 deletions

View file

@ -307,7 +307,7 @@ const VideoJsEvents = ({
});
// player.on('ended', onEnded);
if (isLivestreamClaim) {
if (isLivestreamClaim && player) {
player.liveTracker.on('liveedgechange', async () => {
// Only respond to when we fall behind
if (player.liveTracker.atLiveEdge()) return;

View file

@ -207,12 +207,12 @@ export default React.memo<Props>(function VideoJs(props: Props) {
responsive: true,
controls: true,
html5: {
hls: {
vhs: {
overrideNative: !videojs.browser.IS_ANY_SAFARI,
allowSeeksWithinUnsafeLiveWindow: true,
enableLowInitialPlaylist: false,
handlePartialData: true,
smoothQualityChange: true,
fastQualityChange: true,
},
},
liveTracker: {

View file

@ -15,7 +15,8 @@ export const LIVESTREAM_KILL = 'https://api.stream.odysee.com/stream/kill';
export const MAX_LIVESTREAM_COMMENTS = 50;
export const LIVESTREAM_STATUS_CHECK_INTERVAL = 30 * 1000;
export const LIVESTREAM_STATUS_CHECK_INTERVAL = 45 * 1000;
export const LIVESTREAM_STATUS_CHECK_INTERVAL_SOON = 15 * 1000;
export const LIVESTREAM_STARTS_SOON_BUFFER = 15;
export const LIVESTREAM_STARTED_RECENTLY_BUFFER = 15;
export const LIVESTREAM_UPCOMING_BUFFER = 35;

View file

@ -3,6 +3,7 @@ import { formatLbryChannelName } from 'util/url';
import { lazyImport } from 'util/lazyImport';
import {
LIVESTREAM_STATUS_CHECK_INTERVAL,
LIVESTREAM_STATUS_CHECK_INTERVAL_SOON,
LIVESTREAM_STARTS_SOON_BUFFER,
LIVESTREAM_STARTED_RECENTLY_BUFFER,
} from 'constants/livestream';
@ -98,16 +99,27 @@ export default function LivestreamPage(props: Props) {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [claim, uri, doCommentSocketConnect, doCommentSocketDisconnect]);
// Find out current channels status + active live claim every 30 seconds
const claimReleaseStartingSoonStatic = () =>
release.isBetween(moment(), moment().add(LIVESTREAM_STARTS_SOON_BUFFER, 'minutes'));
const claimReleaseStartedRecentlyStatic = () =>
release.isBetween(moment().subtract(LIVESTREAM_STARTED_RECENTLY_BUFFER, 'minutes'), moment());
// Find out current channels status + active live claim every 30 seconds (or 15 if not live)
const fasterPoll = !isCurrentClaimLive && (claimReleaseStartingSoonStatic() || claimReleaseStartedRecentlyStatic());
React.useEffect(() => {
const fetch = () => doFetchChannelLiveStatus(livestreamChannelId);
fetch();
const intervalId = setInterval(fetch, LIVESTREAM_STATUS_CHECK_INTERVAL);
const intervalId = setInterval(
fetch,
fasterPoll ? LIVESTREAM_STATUS_CHECK_INTERVAL_SOON : LIVESTREAM_STATUS_CHECK_INTERVAL
);
return () => clearInterval(intervalId);
}, [livestreamChannelId, doFetchChannelLiveStatus]);
}, [livestreamChannelId, doFetchChannelLiveStatus, fasterPoll]);
React.useEffect(() => {
setActiveStreamUri(!isCurrentClaimLive && isChannelBroadcasting ? activeLivestreamForChannel.claimUri : false);
@ -117,7 +129,6 @@ export default function LivestreamPage(props: Props) {
if (!isInitialized) return;
const claimReleaseInFuture = () => release.isAfter();
const claimReleaseInPast = () => release.isBefore();
const claimReleaseStartingSoon = () =>
@ -127,7 +138,9 @@ export default function LivestreamPage(props: Props) {
release.isBetween(moment().subtract(LIVESTREAM_STARTED_RECENTLY_BUFFER, 'minutes'), moment());
const checkShowLivestream = () =>
isChannelBroadcasting && isCurrentClaimLive && (claimReleaseInPast() || claimReleaseStartingSoon());
isChannelBroadcasting &&
isCurrentClaimLive &&
(claimReleaseInPast() || claimReleaseStartingSoon() || claimReleaseInFuture());
const checkShowScheduledInfo = () =>
(!isChannelBroadcasting && (claimReleaseInFuture() || claimReleaseStartedRecently())) ||
@ -144,7 +157,7 @@ export default function LivestreamPage(props: Props) {
};
calculateStreamReleaseState();
const intervalId = setInterval(calculateStreamReleaseState, 1000);
const intervalId = setInterval(calculateStreamReleaseState, 5000);
if (isCurrentClaimLive && claimReleaseInPast() && isChannelBroadcasting === true) {
clearInterval(intervalId);

View file

@ -9,6 +9,10 @@ import {
filterUpcomingLiveStreamClaims,
} from 'util/livestream';
import moment from 'moment';
import { isLocalStorageAvailable } from 'util/storage';
import { isEmpty } from 'util/object';
const localStorageAvailable = isLocalStorageAvailable();
const FETCH_ACTIVE_LIVESTREAMS_MIN_INTERVAL_MS = 5 * 60 * 1000;
@ -100,26 +104,35 @@ const findActiveStreams = async (
// Find the first upcoming claim (if one exists) for each channel that's actively broadcasting a stream.
const upcomingClaims = await dispatch(fetchUpcomingLivestreamClaims(channelIDs, lang));
// Filter out any of those claims that aren't scheduled to start within the configured "soon" buffer time (ex. next 5 min).
// Filter out any of those claims that aren't scheduled to start within the configured "soon" buffer time (ex. next 15 min).
const startingSoonClaims = filterUpcomingLiveStreamClaims(upcomingClaims);
// Reduce the claim list to one "live" claim per channel, based on how close each claim's
// release time is to the time the channels stream started.
const allClaims = Object.assign({}, mostRecentClaims, startingSoonClaims);
const allClaims = Object.assign(
{},
mostRecentClaims,
!isEmpty(startingSoonClaims) ? startingSoonClaims : upcomingClaims
);
return determineLiveClaim(allClaims, liveChannels);
};
export const doFetchChannelLiveStatus = (channelId: string) => async (dispatch: Dispatch) => {
const statusForId = `live-status-${channelId}`;
// const localStatus = window.localStorage.getItem(statusForId);
const statusForId = `channel-live-status`;
const localStatus = localStorageAvailable && window.localStorage.getItem(statusForId);
try {
const { channelStatus, channelData } = await fetchLiveChannel(channelId);
// store live state locally, and force 2 non-live statuses before returninig NOT LIVE. This allows for the stream to finish before disposing player.
if (localStatus === LiveStatus.LIVE && channelStatus === LiveStatus.NOT_LIVE) {
localStorageAvailable && window.localStorage.removeItem(statusForId);
return;
}
if (channelStatus === LiveStatus.NOT_LIVE) {
if (channelStatus === LiveStatus.NOT_LIVE && !localStatus) {
dispatch({ type: ACTIONS.REMOVE_CHANNEL_FROM_ACTIVE_LIVESTREAMS, data: { channelId } });
window.localStorage.removeItem(statusForId);
localStorageAvailable && window.localStorage.removeItem(statusForId);
return;
}
@ -136,10 +149,10 @@ export const doFetchChannelLiveStatus = (channelId: string) => async (dispatch:
dispatch({ type: ACTIONS.ADD_CHANNEL_TO_ACTIVE_LIVESTREAMS, data: { ...channelData } });
}
window.localStorage.setItem(statusForId, channelStatus);
localStorageAvailable && window.localStorage.setItem(statusForId, channelStatus);
} catch (err) {
dispatch({ type: ACTIONS.REMOVE_CHANNEL_FROM_ACTIVE_LIVESTREAMS, data: { channelId } });
window.localStorage.removeItem(statusForId);
localStorageAvailable && window.localStorage.removeItem(statusForId);
}
};