Technology

Group Video Watching with Laravel

A group wants to stream videos, with the presenter selecting the movies to watch, controlling the play/pause, and seeking interesting moments. Such a presentation experience is useful for webinars, and education, among others.

We describe how to implement the experience in Laravel with the TALL stack.

#Presentation Events

These events will be broadcast by the presenter:

  1. Choice of video
  2. Play
  3. Pause
  4. Going to a moment in the video

Events are broadcast using Laravel Echo Server, Laravel Websockets, or Soketi. Say on a channel streaming.

#Listening to Events

In the participant Livewire component, we define the listeners:

protected $listeners = [
	'echo:steaming,VideoChoice' => 'process_video_choice',
	'echo:steaming,Play' => 'play',
	'echo:streaming,Pause' => 'pause',
	'echo:streaming,GoToMoment' => 'process_goto'
];

#Processing Events

Each event is dispatched to the front-end Alpine.js code using dispatchBrowserEvent.

For example, for going to a video moment, on the instruction of the presenter,

private function process_goto($data) 
{
	$moment = $data['moment];
	
	$this->dispatchBrowserEvent('goto-moment', ['moment' => $moment]); 
}

#Controlling the Video in the Browser

In Alpine.js, we listen to events from Livewire and then:

  1. Go to the desired video moment
  2. Switch the video
  3. Play
  4. Pause

For example, for going to a moment and for switching videos,

<video x-ref="video" 
	x-data="{ play: false }" 
	@goto-moment.window="$refs.video.currentTime = event.detail.moment"
	@video-choice.window="$refs.video.src = event.detail.video_file_path; $refs.video.load();"
>
   
</video>

#Presenter Interface

A web page with a list of videos and a video player.

For simplicity, assume the presenter has on the web page an HTML video element.

Play and pause on the video element are sent from Alpine.js using,

Livewire.emit('play');
Livewire.emit('pause');

and when going to some moment in the video,

Livewire.emit('seek', { 'moment': $this.refs.video.currentTime });

To be processed in Livewire, in a listener,

protected $listeners = ['seek' => 'process_seek'];

public function process_seek($data)
{
    $moment = $payload['moment'];
}
Yoram Kornatzky

Yoram Kornatzky