[HTML 5] Video

Binding to Media Events

import './assets/css/style.css';
import autumnMp4 from './assets/media/autumn.mp4';

const app = document.getElementById('app');
app.innerHTML = `
  <h1>JavaScript HTML5 APIs</h1>
  <div class="player">
    <video class="media" controls>
      <source src="${autumnMp4}" type="video/mp4">
      <p>
        HTML5 Video is not supported. 
        <a href="${autumnMp4}">Download this video</a> instead.
      </p>
    </video>
  </div>
`;

const player = document.querySelector('.player');
const media = player.querySelector('.media');

media.addEventListener('durationchange', (e) => console.log(e.target.duration));
media.addEventListener('canplay', () => console.log('Ready!'));
media.addEventListener('canplaythrough', () =>
  console.log('Can Play Through!')
);
media.addEventListener('timeupdate', (e) => console.log(e.target.currentTime));

media.addEventListener('play', (e) => console.log('Play', !e.target.paused));
media.addEventListener('playing', () => console.log('Playing'));
media.addEventListener('pause', (e) => console.log('Pause', e.target.paused));
media.addEventListener('ended', () => console.log('Ended'));

 

Custom Play, Pause and Stop Controls

import './assets/css/style.css';
import autumnMp4 from './assets/media/autumn.mp4';

import playIcon from './assets/img/icons/play.svg';
import pauseIcon from './assets/img/icons/pause.svg';
import stopIcon from './assets/img/icons/stop.svg';

const app = document.getElementById('app');
app.innerHTML = `
  <h1>JavaScript HTML5 APIs</h1>
  <div class="player">
    <video class="media" controls>
      <source src="${autumnMp4}" type="video/mp4">
      <p>
        HTML5 Video is not supported. 
        <a href="${autumnMp4}">Download this video</a> instead.
      </p>
    </video>
    <div class="player__controls">
      <button type="button" class="player__play" aria-label="Play Pause">
        <img src="${playIcon}" alt="Play Pause Icon">
      </button>
      <button type="button" class="player__stop" aria-label="Stop">
        <img src="${stopIcon}" alt="Stop Icon">
      </button>
    </div>
  </div>
`;

const player = document.querySelector('.player');
const play = player.querySelector('.player__play');
const playImg = play.querySelector('img');
const stop = player.querySelector('.player__stop');
const media = player.querySelector('.media');

const toggleMediaStatus = () => {
  if (media.paused) {
    media.play();
    playImg.src = pauseIcon;
  } else {
    media.pause();
    playImg.src = playIcon;
  }
};

const stopMedia = () => {
  media.pause();
  media.currentTime = 0;
  playImg.src = playIcon;
};

play.addEventListener('click', toggleMediaStatus);
stop.addEventListener('click', stopMedia);

 

Syncing Medai Progressing

import './assets/css/style.css';
import autumnMp4 from './assets/media/autumn.mp4';

import playIcon from './assets/img/icons/play.svg';
import pauseIcon from './assets/img/icons/pause.svg';
import stopIcon from './assets/img/icons/stop.svg';

const app = document.getElementById('app');
app.innerHTML = `
  <h1>JavaScript HTML5 APIs</h1>
  <div class="player">
    <video class="media" controls>
      <source src="${autumnMp4}" type="video/mp4">
      <p>
        HTML5 Video is not supported. 
        <a href="${autumnMp4}">Download this video</a> instead.
      </p>
    </video>
    <div class="player__controls">
      <button type="button" class="player__play" aria-label="Play Pause">
        <img src="${playIcon}" alt="Play Pause Icon">
      </button>
      <button type="button" class="player__stop" aria-label="Stop">
        <img src="${stopIcon}" alt="Stop Icon">
      </button>
      <div class="player__progress">
        <input type="range" class="player__timeline" min="0" max="100" value="0">
        <span class="player__duration"></span>
      </div>
    </div>
  </div>
`;

const player = document.querySelector('.player');
const play = player.querySelector('.player__play');
const playImg = play.querySelector('img');
const stop = player.querySelector('.player__stop');
const media = player.querySelector('.media');
const timeline = player.querySelector('.player__timeline');
const duration = player.querySelector('.player__duration');

let totalDuration;

const toggleMediaStatus = () => {
  if (media.paused) {
    media.play();
    playImg.src = pauseIcon;
  } else {
    media.pause();
    playImg.src = playIcon;
  }
};

const stopMedia = () => {
  media.pause();
  media.currentTime = 0;
  playImg.src = playIcon;
};

const getTime = (duration) => {
  const time = parseInt(duration.toFixed(), 10);
  const minutes = `${parseInt(time / 60)}`.padStart(2, 0);
  const seconds = `${time % 60}`.padStart(2, 0);
  return `${minutes}:${seconds}`;
};

const setInitialDuration = (e) => {
  totalDuration = getTime(e.target.duration);
  duration.innerText = `00:00 / ${totalDuration}`;
};

const setDuration = (e) => {
  const currentDuration = getTime(e.target.currentTime);
  const progress = (e.target.currentTime / e.target.duration) * 100;
  timeline.value = progress;
  duration.innerText = `${currentDuration} / ${totalDuration}`;
};

play.addEventListener('click', toggleMediaStatus);
stop.addEventListener('click', stopMedia);

media.addEventListener('durationchange', setInitialDuration);
media.addEventListener('timeupdate', setDuration);
media.addEventListener('ended', stopMedia);

 

Scrubbing Duration with <input type=”range”>

import './assets/css/style.css';
import autumnMp4 from './assets/media/autumn.mp4';

import playIcon from './assets/img/icons/play.svg';
import pauseIcon from './assets/img/icons/pause.svg';
import stopIcon from './assets/img/icons/stop.svg';

const app = document.getElementById('app');
app.innerHTML = `
  <h1>JavaScript HTML5 APIs</h1>
  <div class="player">
    <video class="media" controls>
      <source src="${autumnMp4}" type="video/mp4">
      <p>
        HTML5 Video is not supported. 
        <a href="${autumnMp4}">Download this video</a> instead.
      </p>
    </video>
    <div class="player__controls">
      <button type="button" class="player__play" aria-label="Play Pause">
        <img src="${playIcon}" alt="Play Pause Icon">
      </button>
      <button type="button" class="player__stop" aria-label="Stop">
        <img src="${stopIcon}" alt="Stop Icon">
      </button>
      <div class="player__progress">
        <input type="range" class="player__timeline" min="0" max="100" value="0">
        <span class="player__duration"></span>
      </div>
    </div>
  </div>
`;

const player = document.querySelector('.player');
const play = player.querySelector('.player__play');
const playImg = play.querySelector('img');
const stop = player.querySelector('.player__stop');
const media = player.querySelector('.media');
const timeline = player.querySelector('.player__timeline');
const duration = player.querySelector('.player__duration');

let totalDuration;

const toggleMediaStatus = () => {
  if (media.paused) {
    media.play();
    playImg.src = pauseIcon;
  } else {
    media.pause();
    playImg.src = playIcon;
  }
};

const stopMedia = () => {
  media.pause();
  media.currentTime = 0;
  playImg.src = playIcon;
};

const getTime = (duration) => {
  const time = parseInt(duration.toFixed(), 10);
  const minutes = `${parseInt(time / 60)}`.padStart(2, 0);
  const seconds = `${time % 60}`.padStart(2, 0);
  return `${minutes}:${seconds}`;
};

const setInitialDuration = (e) => {
  totalDuration = getTime(e.target.duration);
  duration.innerText = `00:00 / ${totalDuration}`;
};

const setDuration = (e) => {
  const currentDuration = getTime(e.target.currentTime);
  const progress = (e.target.currentTime / e.target.duration) * 100;
  timeline.value = progress;
  duration.innerText = `${currentDuration} / ${totalDuration}`;
};

const skipToPosition = (e) => {
  const position = parseInt(e.target.value, 10) / 100;
  media.currentTime = media.duration * position;
};

play.addEventListener('click', toggleMediaStatus);
stop.addEventListener('click', stopMedia);

media.addEventListener('durationchange', setInitialDuration);
media.addEventListener('timeupdate', setDuration);
media.addEventListener('ended', stopMedia);
timeline.addEventListener('input', skipToPosition);

 

Scrubbing Volume Levels and Mute Functionality

import './assets/css/style.css';
import autumnMp4 from './assets/media/autumn.mp4';

import playIcon from './assets/img/icons/play.svg';
import pauseIcon from './assets/img/icons/pause.svg';
import stopIcon from './assets/img/icons/stop.svg';
import volumeIcon from './assets/img/icons/volume.svg';
import volumeMuteIcon from './assets/img/icons/volume-mute.svg';

const app = document.getElementById('app');
app.innerHTML = `
  <h1>JavaScript HTML5 APIs</h1>
  <div class="player">
    <video class="media" controls>
      <source src="${autumnMp4}" type="video/mp4">
      <p>
        HTML5 Video is not supported. 
        <a href="${autumnMp4}">Download this video</a> instead.
      </p>
    </video>
    <div class="player__controls">
      <button type="button" class="player__play" aria-label="Play Pause">
        <img src="${playIcon}" alt="Play Pause Icon">
      </button>
      <button type="button" class="player__stop" aria-label="Stop">
        <img src="${stopIcon}" alt="Stop Icon">
      </button>
      <div class="player__progress">
        <input type="range" class="player__timeline" min="0" max="100" value="0">
        <span class="player__duration"></span>
      </div>
      <div class="player__sound">
        <img src="${volumeIcon}" class="player__mute" alt="Volume Icon">
        <input type="range" class="player__volume" min="0" max="100" value="100">
      </div>
    </div>
  </div>
`;

const player = document.querySelector('.player');
const play = player.querySelector('.player__play');
const playImg = play.querySelector('img');
const stop = player.querySelector('.player__stop');
const media = player.querySelector('.media');
const timeline = player.querySelector('.player__timeline');
const duration = player.querySelector('.player__duration');
const volume = player.querySelector('.player__volume');
const volumeToggle = player.querySelector('.player__mute');

let totalDuration;

const toggleMediaStatus = () => {
  if (media.paused) {
    media.play();
    playImg.src = pauseIcon;
  } else {
    media.pause();
    playImg.src = playIcon;
  }
};

const stopMedia = () => {
  media.pause();
  media.currentTime = 0;
  playImg.src = playIcon;
};

const getTime = (duration) => {
  const time = parseInt(duration.toFixed(), 10);
  const minutes = `${parseInt(time / 60)}`.padStart(2, 0);
  const seconds = `${time % 60}`.padStart(2, 0);
  return `${minutes}:${seconds}`;
};

const setInitialDuration = (e) => {
  totalDuration = getTime(e.target.duration);
  duration.innerText = `00:00 / ${totalDuration}`;
};

const setDuration = (e) => {
  const currentDuration = getTime(e.target.currentTime);
  const progress = (e.target.currentTime / e.target.duration) * 100;
  timeline.value = progress;
  duration.innerText = `${currentDuration} / ${totalDuration}`;
};

const skipToPosition = (e) => {
  const position = parseInt(e.target.value, 10) / 100;
  media.currentTime = media.duration * position;
};

const setVolume = (e) => {
  const position = parseInt(e.target.value, 10) / 100;
  media.volume = position;
  volumeToggle.src = media.volume > 0 ? volumeIcon : volumeMuteIcon;
};

const toggleVolume = () => {
  const isMuted = media.volume === 0;
  volumeToggle.src = isMuted ? volumeIcon : volumeMuteIcon;
  volume.value = isMuted ? 100 : 0;
  volume.dispatchEvent(new Event('input'));
  // media.volume = isMuted ? 1 : 0;
};

play.addEventListener('click', toggleMediaStatus);
stop.addEventListener('click', stopMedia);

media.addEventListener('durationchange', setInitialDuration);
media.addEventListener('timeupdate', setDuration);
media.addEventListener('ended', stopMedia);

timeline.addEventListener('input', skipToPosition);
volume.addEventListener('input', setVolume);
volumeToggle.addEventListener('click', toggleVolume);

 

Picture-in-Picture (PiP) Mode

import './assets/css/style.css';
import autumnMp4 from './assets/media/autumn.mp4';

import playIcon from './assets/img/icons/play.svg';
import pauseIcon from './assets/img/icons/pause.svg';
import stopIcon from './assets/img/icons/stop.svg';
import volumeIcon from './assets/img/icons/volume.svg';
import volumeMuteIcon from './assets/img/icons/volume-mute.svg';
import pipIcon from './assets/img/icons/popup.svg';

const app = document.getElementById('app');
app.innerHTML = `
  <h1>JavaScript HTML5 APIs</h1>
  <div class="player">
    <video class="media" controls>
      <source src="${autumnMp4}" type="video/mp4">
      <p>
        HTML5 Video is not supported. 
        <a href="${autumnMp4}">Download this video</a> instead.
      </p>
    </video>
    <div class="player__controls">
      <button type="button" class="player__play" aria-label="Play Pause">
        <img src="${playIcon}" alt="Play Pause Icon">
      </button>
      <button type="button" class="player__stop" aria-label="Stop">
        <img src="${stopIcon}" alt="Stop Icon">
      </button>
      <div class="player__progress">
        <input type="range" class="player__timeline" min="0" max="100" value="0">
        <span class="player__duration"></span>
      </div>
      
      <button type="button" class="player__pip" aria-label="Picture-in-Picture">
        <img src="${pipIcon}" alt="Picture-in-Picture Icon">
      </button>
      <div class="player__sound">
        <img src="${volumeIcon}" class="player__mute" alt="Volume Icon">
        <input type="range" class="player__volume" min="0" max="100" value="100">
      </div>
    </div>
  </div>
`;

const player = document.querySelector('.player');
const play = player.querySelector('.player__play');
const playImg = play.querySelector('img');
const stop = player.querySelector('.player__stop');
const media = player.querySelector('.media');
const timeline = player.querySelector('.player__timeline');
const duration = player.querySelector('.player__duration');
const volume = player.querySelector('.player__volume');
const volumeToggle = player.querySelector('.player__mute');
const pip = player.querySelector('.player__pip');

let totalDuration;

const toggleMediaStatus = () => {
  if (media.paused) {
    media.play();
    playImg.src = pauseIcon;
  } else {
    media.pause();
    playImg.src = playIcon;
  }
};

const stopMedia = () => {
  media.pause();
  media.currentTime = 0;
  playImg.src = playIcon;
};

const getTime = (duration) => {
  const time = parseInt(duration.toFixed(), 10);
  const minutes = `${parseInt(time / 60)}`.padStart(2, 0);
  const seconds = `${time % 60}`.padStart(2, 0);
  return `${minutes}:${seconds}`;
};

const setInitialDuration = (e) => {
  totalDuration = getTime(e.target.duration);
  duration.innerText = `00:00 / ${totalDuration}`;
};

const setDuration = (e) => {
  const currentDuration = getTime(e.target.currentTime);
  const progress = (e.target.currentTime / e.target.duration) * 100;
  timeline.value = progress;
  duration.innerText = `${currentDuration} / ${totalDuration}`;
};

const skipToPosition = (e) => {
  const position = parseInt(e.target.value, 10) / 100;
  media.currentTime = media.duration * position;
};

const setVolume = (e) => {
  const position = parseInt(e.target.value, 10) / 100;
  media.volume = position;
  volumeToggle.src = media.volume > 0 ? volumeIcon : volumeMuteIcon;
};

const toggleVolume = () => {
  const isMuted = media.volume === 0;
  volumeToggle.src = isMuted ? volumeIcon : volumeMuteIcon;
  volume.value = isMuted ? 100 : 0;
  volume.dispatchEvent(new Event('input'));
};

play.addEventListener('click', toggleMediaStatus);
stop.addEventListener('click', stopMedia);

media.addEventListener('durationchange', setInitialDuration);
media.addEventListener('timeupdate', setDuration);
media.addEventListener('ended', stopMedia);

timeline.addEventListener('input', skipToPosition);
volume.addEventListener('input', setVolume);
volumeToggle.addEventListener('click', toggleVolume);

const initPictureInPicture = () => {
  pip.addEventListener('click', () => {
    if (!document.pictureInPictureElement) {
      media.requestPictureInPicture();
    } else {
      document.exitPictureInPicture();
    }
  });

  media.addEventListener('enterpictureinpicture', () => {
    console.log('Entered PiP');
  });
  media.addEventListener('leavepictureinpicture', () => {
    console.log('Left PiP');
  });
};

if ('pictureInPictureEnabled' in document) {
  initPictureInPicture();
}

 

Using the new Audio() constructor

import './assets/css/style.css';
import autumnMp3 from './assets/media/autumn.mp3';
import autumnMp4 from './assets/media/autumn.mp4';

import playIcon from './assets/img/icons/play.svg';
import pauseIcon from './assets/img/icons/pause.svg';
import stopIcon from './assets/img/icons/stop.svg';
import volumeIcon from './assets/img/icons/volume.svg';
import volumeMuteIcon from './assets/img/icons/volume-mute.svg';
import pipIcon from './assets/img/icons/popup.svg';

const app = document.getElementById('app');
app.innerHTML = `
  <h1>JavaScript HTML5 APIs</h1>
  <div class="player">
    <!--<audio class="media">
      <source src="${autumnMp3}" type="audio/mpeg">
    </audio>-->
    <!--<video class="media" controls>
      <source src="${autumnMp4}" type="video/mp4">
      <p>
        HTML5 Video is not supported. 
        <a href="${autumnMp4}">Download this video</a> instead.
      </p>
    </video>-->
    <div class="player__controls">
      <button type="button" class="player__play" aria-label="Play Pause">
        <img src="${playIcon}" alt="Play Pause Icon">
      </button>
      <button type="button" class="player__stop" aria-label="Stop">
        <img src="${stopIcon}" alt="Stop Icon">
      </button>
      <div class="player__progress">
        <input type="range" class="player__timeline" min="0" max="100" value="0">
        <span class="player__duration"></span>
      </div>
      
      <button type="button" class="player__pip" aria-label="Picture-in-Picture">
        <img src="${pipIcon}" alt="Picture-in-Picture Icon">
      </button>
      <div class="player__sound">
        <img src="${volumeIcon}" class="player__mute" alt="Volume Icon">
        <input type="range" class="player__volume" min="0" max="100" value="100">
      </div>
    </div>
  </div>
`;

const player = document.querySelector('.player');
const play = player.querySelector('.player__play');
const playImg = play.querySelector('img');
const stop = player.querySelector('.player__stop');
const media = new Audio(autumnMp3);
const timeline = player.querySelector('.player__timeline');
const duration = player.querySelector('.player__duration');
const volume = player.querySelector('.player__volume');
const volumeToggle = player.querySelector('.player__mute');
const pip = player.querySelector('.player__pip');

let totalDuration;

const toggleMediaStatus = () => {
  if (media.paused) {
    media.play();
    playImg.src = pauseIcon;
  } else {
    media.pause();
    playImg.src = playIcon;
  }
};

const stopMedia = () => {
  media.pause();
  media.currentTime = 0;
  playImg.src = playIcon;
};

const getTime = (duration) => {
  const time = parseInt(duration.toFixed(), 10);
  const minutes = `${parseInt(time / 60)}`.padStart(2, 0);
  const seconds = `${time % 60}`.padStart(2, 0);
  return `${minutes}:${seconds}`;
};

const setInitialDuration = (e) => {
  totalDuration = getTime(e.target.duration);
  duration.innerText = `00:00 / ${totalDuration}`;
};

const setDuration = (e) => {
  const currentDuration = getTime(e.target.currentTime);
  const progress = (e.target.currentTime / e.target.duration) * 100;
  timeline.value = progress;
  duration.innerText = `${currentDuration} / ${totalDuration}`;
};

const skipToPosition = (e) => {
  const position = parseInt(e.target.value, 10) / 100;
  media.currentTime = media.duration * position;
};

const setVolume = (e) => {
  const position = parseInt(e.target.value, 10) / 100;
  media.volume = position;
  volumeToggle.src = media.volume > 0 ? volumeIcon : volumeMuteIcon;
};

const toggleVolume = () => {
  const isMuted = media.volume === 0;
  volumeToggle.src = isMuted ? volumeIcon : volumeMuteIcon;
  volume.value = isMuted ? 100 : 0;
  volume.dispatchEvent(new Event('input'));
};

play.addEventListener('click', toggleMediaStatus);
stop.addEventListener('click', stopMedia);

media.addEventListener('durationchange', setInitialDuration);
media.addEventListener('timeupdate', setDuration);
media.addEventListener('ended', stopMedia);

timeline.addEventListener('input', skipToPosition);
volume.addEventListener('input', setVolume);
volumeToggle.addEventListener('click', toggleVolume);

const initPictureInPicture = () => {
  pip.addEventListener('click', () => {
    if (!document.pictureInPictureElement) {
      media.requestPictureInPicture();
    } else {
      document.exitPictureInPicture();
    }
  });

  media.addEventListener('enterpictureinpicture', () => {
    console.log('Entered PiP');
  });
  media.addEventListener('leavepictureinpicture', () => {
    console.log('Left PiP');
  });
};

if ('pictureInPictureEnabled' in document) {
  initPictureInPicture();
}

 

posted @ 2023-01-02 01:59  Zhentiw  阅读(17)  评论(0编辑  收藏  举报