There is an old and meanwhile deprecated API which was meant for doing exactly that. It's called MediaController
and there is still an implementation in Safari today.
Assigning both media elements to the same controller should be enough to sync them with each other.
<video controller="audio-and-video" src="video.file"></video>
<audio controller="audio-and-video" src="audio.file"></audio>
There is a more flexible thing called a TimingObject
that can be used as well. It's not implemented in any browser but can be implemented in pure JavaScript. Let's imagine the HTML is the same as above.
<video id="video" src="video.file"></video>
<audio id="audio" src="audio.file"></audio>
It's then possible to use a bit of JavaScript to sync both media elements to the same TimingObject
.
import { TimingObject } from 'timing-object';
import { setTimingsrc } from 'timingsrc';
const videoElement = document.getElementsById('video');
const audioElement = document.getElementsById('audio');
const timingObject = new TimingObject();
setTimingsrc(videoElement, timingObject);
setTimingsrc(audioElement, timingObject);
Instead of calling play()
and pause()
on one of the media elements you would then control the playback by updating the TimingObject
.
// play
timingObject.update({ velocity: 1 });
// pause
timingObject.update({ velocity: 0 });