Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: hls video streaming #684

Merged
merged 2 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 46 additions & 0 deletions src/lib/assets/icons/social/IconMobileAppiOS.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
126 changes: 56 additions & 70 deletions src/lib/components/Channel/Stream/VideoItem.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,9 @@
let role = '',
coloredRole: any = {},
isGuest = false,
obsElement: HTMLVideoElement,
screenElement: HTMLVideoElement,
webcamElement: HTMLVideoElement,
audioElement: HTMLAudioElement,
obsWhep: WHIPClient,
screenWhip: WHIPClient,
screenWhep: WHEPClient,
webcamWhip: WHIPClient,
Expand All @@ -47,12 +45,16 @@
timerInterval: any,
formattedTime: string = '00:00:00',
isHoverVideo: boolean = false,
obs_modal: any = null
obs_modal: any = null,
player: any,
hlsUrl: string = '',
hasActiveObsStream = false

// WHIP/WHEP variables that determine if stream is coming in
$: isScreenLive = false
$: isWebcamLive = false
$: hlsUrl = ''

$: console.log('TESTING HLS', hlsUrl)

$: if (channel) {
role = setRole({ userId: video._id, channel, currentUserId: $page.data.user?.userId })
Expand Down Expand Up @@ -87,14 +89,14 @@
handleAudioChanges()
}

$: if ($is_feature_stats_enabled && (isScreenLive || isWebcamLive)) {
$: if ($is_feature_stats_enabled && (isScreenLive || isWebcamLive || hasActiveObsStream)) {
toggleTimer()
}

$: animate = isWebcamFocused ? '' : 'transition-all'

const handleObsChanges = () => {
prevScreen = video.obs
prevObs = video.obs
toggleClient({
trackType: 'obs'
})
Expand Down Expand Up @@ -124,31 +126,6 @@
case 'obs':
hlsUrl = video.obs?.playback?.hls
console.log('got here---- video.obs.playback?.hls', hlsUrl)
// if (video.obs && $is_sharing_obs) {
// const key = video.obs.webRTCPlayback.url + '-' + video._id
// const existed = getScreen(key)
// obsWhep =
// existed ||
// new WHEPClient(video.obs.webRTCPlayback.url, obsElement, video.obs.trackType)
// if (existed) {
// existed.videoElement = obsElement
// obsElement.srcObject = existed.localStream
// $is_sharing_obs = true
// isScreenLive = true
// }
// addScreen(key, obsWhep)
// obsWhep.addEventListener(`localStreamStopped-${trackType}`, () => {
// $is_sharing_obs = false
// isScreenLive = false
// removeScreen(key)
// })
// obsWhep.addEventListener(`isScreenLive`, (ev: any) => (isScreenLive = ev.detail))
// } else if (!video.screen) {
// if (obsElement) {
// obsElement.srcObject = null
// }
// $is_sharing_obs = false
// }
break
case 'screen':
if (video.screen && $is_sharing_screen) {
Expand Down Expand Up @@ -212,13 +189,8 @@
} else {
switch (trackType) {
case 'obs':
if (video.obs && obsElement) {
obsElement.src = video.obs?.playback?.hls
obsElement.muted = false
obsElement.play()
} else {
if (obsElement) obsElement.srcObject = null
}
hlsUrl = video.obs?.playback?.hls
console.log('got here---- video.obs.playback?.hls', hlsUrl)
break
case 'screen':
if (video.screen && screenElement) {
Expand Down Expand Up @@ -286,16 +258,7 @@

onMount(() => {
isGuest = channel?.guests?.includes(video._id)
if (obsElement) {
obsElement.addEventListener('dblclick', (event: any) => {
if (document.fullscreenElement) {
document.exitFullscreen()
} else {
obsElement.requestFullscreen()
}
})
handleObsChanges()
}
handleObsChanges()

if (screenElement) {
screenElement.addEventListener('dblclick', (event: any) => {
Expand Down Expand Up @@ -327,7 +290,8 @@

is_sharing_obs.subscribe((value: any) => {
if (value === false) {
obsWhep?.disconnectStream()
// obsWhep?.disconnectStream()
//TODO: check if stream is coming, if not, hide video
} else if (value === true) {
if (is_sharing_obs) obs_modal?.showModal()
}
Expand Down Expand Up @@ -416,12 +380,17 @@
}, 1000)
}
}

const onPlaybackReady = (e: any) => {
console.log('onPlaybackReady', e)
hasActiveObsStream = true
}
</script>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@vime/core@^5/themes/default.css" />

<div
class={isScreenLive || isWebcamLive ? 'w-full h-full' : 'w-[500px] max-h-80'}
class={hlsUrl || isScreenLive || isWebcamLive ? 'w-full h-full' : 'w-[500px] max-h-80'}
on:mouseenter={() => (isHoverVideo = true)}
on:mouseleave={() => (isHoverVideo = false)}>
<div class="bg-base-200 relative w-full h-full rounded-md">
Expand All @@ -432,33 +401,30 @@
? 'mask-hexagon'
: 'mask-squircle'} object-cover m-auto" />
<div class="absolute inset-0">
{#if $is_feature_stats_enabled && (isScreenLive || isWebcamLive)}
{#if $is_feature_stats_enabled && (isScreenLive || isWebcamLive || hasActiveObsStream)}
<span
class="btn btn-sm btn-neutral font-medium text-white border-none items-center w-fit absolute top-2 left-2 {isHoverVideo
? 'opacity-100'
: 'opacity-50'}">
{formattedTime}
</span>
{/if}
{#if $is_feature_obs_enabled}
<!-- <video-js
bind:this={obsElement}
id={`obs-${video._id}`}
controls
autoplay
muted
preload="auto"
class="rounded-md w-full h-full">
<source src={video.obs?.hlsPlayback} type="application/x-mpegURL" />
</video-js> -->

<Player theme="dark" style="--vm-player-theme: #e86c8b;">
<Hls crossOrigin>
<source data-src={hlsUrl} type="application/x-mpegURL" />
</Hls>

<DefaultUi />
</Player>
{#if $is_feature_obs_enabled && hlsUrl}
<div class="absolute rounded-md w-full h-full">
<Player
theme="dark"
on:vmPlaybackReady={onPlaybackReady}
bind:this={player}
controls
autoplay
muted>
<Hls crossOrigin>
<source data-src={hlsUrl} type="application/x-mpegURL" />
</Hls>

<DefaultUi />
</Player>
</div>
{/if}

<video
Expand Down Expand Up @@ -548,3 +514,23 @@
</form>
</dialog>
{/if}

<!-- <style>
:global(html),
:global(body) {
width: 100%;
height: 100%;
}

:global(body) {
margin: 0;
display: flex;
align-items: center;
justify-content: center;
}

#container {
width: 100%;
max-width: 960px;
}
</style> -->
15 changes: 11 additions & 4 deletions src/lib/components/Global/DrawerMain.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
is_feature_apps_enabled
} from '$lib/stores/remoteConfigStore'
import IconMageText from '$lib/assets/icons/IconMageText.svelte'
import { is_login_modal_open } from '$lib/stores/helperStore'
import { is_apps_modal_open, is_login_modal_open } from '$lib/stores/helperStore'
import { colorFromLevel, levelAndBarValueFromExp } from '$lib/utils'
import { onMount } from 'svelte'
import { isOnline } from '$lib/stores/userStore'
Expand Down Expand Up @@ -190,7 +190,7 @@
<button
class="custom-menu-item text-accent hover:text-accent font-medium"
on:click={() => {
$is_login_modal_open = true
$is_apps_modal_open = true
if (nav_drawer.checked) {
nav_drawer.checked = false
}
Expand All @@ -206,13 +206,20 @@
{/if}
{#if $is_feature_apps_enabled}
<li>
<a class="custom-menu-item" href="https://codecrow.io" target="_blank">
<button
class="custom-menu-item"
on:click={() => {
$is_apps_modal_open = true
if (nav_drawer.checked) {
nav_drawer.checked = false
}
}}>
<IconDrawerGetApps />
<span class={isChannelPage ? 'md:hidden' : ''}>Get Apps</span>
{#if !isChannelPage}
<span class="badge badge-secondary">New</span>
{/if}
</a>
</button>
</li>
{/if}
<li>
Expand Down
30 changes: 30 additions & 0 deletions src/lib/components/Global/MobileAppsPrompt.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script lang="ts">
import { is_apps_modal_open } from '$lib/stores/helperStore'
import IconMobileAppiOS from '$lib/assets/icons/social/IconMobileAppiOS.svg'
import IconMobileAppAndroid from '$lib/assets/icons/social/IconMobileAppAndroid.png'
</script>

<div
class="modal cursor-pointer {$is_apps_modal_open ? 'modal-open' : ''}"
on:click={() => {
$is_apps_modal_open = false
}}>
<div
class="modal-box relative"
on:click={(e) => {
e.stopPropagation()
}}>
<h3 class="font-bold text-lg">Download the mobile app</h3>
<div class="py-4 space-y-5 px-4 md:px-10">
<a
href="https://play.google.com/store/apps/details?id=com.google.android.apps.messaging&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1"
><img alt="Get it on Google Play" src={IconMobileAppAndroid} /></a>
<a
href="https://apps.apple.com/us/app/telegram-messenger/id686449807?itsct=apps_box_badge&amp;itscg=30200">
<img src={IconMobileAppiOS} alt="Download on the App Store" class="w-full h-full p-6" /></a>
</div>
<div class="modal-action">
<button class="btn" on:click={() => ($is_apps_modal_open = false)}>Close</button>
</div>
</div>
</div>
1 change: 1 addition & 0 deletions src/lib/stores/helperStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { writable, type Writable } from 'svelte/store'
const profiles: any = {}

export const is_login_modal_open: Writable<any> = writable(null)
export const is_apps_modal_open: Writable<any> = writable(null)
export const current_theme: Writable<string> = writable('dark')

export const setProfile = (id: string, profile: any) => {
Expand Down
4 changes: 4 additions & 0 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
} from '$lib/stores/remoteConfigStore'
import { env } from '$env/dynamic/public'
import { user_role } from '$lib/stores/userStore'
import MobileAppsPrompt from '$lib/components/Global/MobileAppsPrompt.svelte'

NProgress.configure({
minimum: 0.75,
Expand Down Expand Up @@ -142,6 +143,9 @@

<slot />
<LoginPrompt />
{#if $is_feature_apps_enabled}
<MobileAppsPrompt />
{/if}
</div>
<div class="drawer-side z-10">
<label for="main-drawer" class="drawer-overlay" />
Expand Down