阿里云主机折上折
  • 微信号
Current Site:Index > Multimedia events ('onplay', 'onpause', 'onended', etc.)

Multimedia events ('onplay', 'onpause', 'onended', etc.)

Author:Chuan Chen 阅读数:27002人阅读 分类: HTML

Multimedia plays a crucial role in modern web pages, and HTML5 provides a series of events to precisely control the playback behavior of audio and video. Events such as onplay, onpause, and onended allow developers to capture user interactions or media state changes, enabling dynamic responses.

onplay Event

The onplay event is triggered when media starts playing or resumes from a paused state. Typical scenarios include:

  • Updating the play/pause button state on the interface
  • Starting playback duration recording
  • Triggering animation effects
<video id="myVideo" controls>
  <source src="video.mp4" type="video/mp4">
</video>

<script>
  const video = document.getElementById('myVideo');
  video.onplay = function() {
    console.log('Video playback started');
    document.querySelector('.play-btn').textContent = '⏸';
  };
</script>

Real-world example: Video platforms automatically hide the control bar during playback and fade it out after 3 seconds of inactivity. The onplay event can be used to reset the fade-out timer:

let hideTimer;
video.onplay = () => {
  clearTimeout(hideTimer);
  controls.style.opacity = '1';
  hideTimer = setTimeout(() => {
    controls.style.opacity = '0';
  }, 3000);
};

onpause Event

The onpause event is triggered when playback is paused or the pause() method is called programmatically. Common uses include:

  • Saving the current playback position
  • Displaying the paused state UI
  • Pausing related animations
video.onpause = () => {
  localStorage.setItem('videoPosition', video.currentTime);
  document.querySelector('.play-btn').textContent = '▶';
};

Advanced usage: Combining with requestAnimationFrame to achieve frame-accurate screenshots when paused:

let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');

video.onpause = () => {
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;
  ctx.drawImage(video, 0, 0);
  document.body.appendChild(canvas);
};

onended Event

The onended event is triggered when media playback completes. It is suitable for:

  • Auto-playing the next episode
  • Displaying recommended content at the end
  • Resetting the player state
video.onended = () => {
  if (playlist.length > 0) {
    video.src = playlist.shift();
    video.play();
  }
};

Live streaming extension: Automatically switching to recorded playback when the live stream ends:

const liveStream = document.getElementById('live');
const replayStream = document.getElementById('replay');

liveStream.onended = () => {
  liveStream.style.display = 'none';
  replayStream.style.display = 'block';
  replayStream.play();
};

Other Related Events

ontimeupdate Event

Continuously triggered when the playback position changes, suitable for:

  • Real-time progress bar updates
  • Subtitle synchronization
  • Time-based interactive features
video.ontimeupdate = () => {
  const progress = (video.currentTime / video.duration) * 100;
  progressBar.style.width = `${progress}%`;
  
  // Implementing chapter navigation
  chapters.forEach(chapter => {
    if (video.currentTime >= chapter.start && 
        video.currentTime < chapter.end) {
      chapterNav.classList.add('active');
    }
  });
};

onvolumechange Event

Triggered when the volume changes or the mute state is toggled:

video.onvolumechange = () => {
  volumeDisplay.textContent = Math.round(video.volume * 100);
  muteBtn.classList.toggle('active', video.muted);
};

onwaiting and onplaying Events

Triggered when buffering state changes, used to display loading indicators:

const spinner = document.querySelector('.spinner');

video.onwaiting = () => spinner.style.display = 'block';
video.onplaying = () => spinner.style.display = 'none';

Combined Event Applications

Implementing a complete player control logic:

const video = document.getElementById('videoPlayer');
const controls = {
  playBtn: document.querySelector('.play-btn'),
  timeDisplay: document.querySelector('.time'),
  progress: document.querySelector('.progress-bar')
};

// Comprehensive event handling
video.onplay = () => {
  controls.playBtn.textContent = '❚❚';
  startPlaybackAnalytics();
};

video.onpause = () => {
  controls.playBtn.textContent = '►';
  sendPlaybackAnalytics();
};

video.onended = () => {
  showRecommendations();
  resetPlayer();
};

video.ontimeupdate = () => {
  const minutes = Math.floor(video.currentTime / 60);
  const seconds = Math.floor(video.currentTime % 60);
  controls.timeDisplay.textContent = 
    `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
  
  const progress = (video.currentTime / video.duration) * 100;
  controls.progress.style.width = `${progress}%`;
};

// Custom methods
function startPlaybackAnalytics() {
  // Implement playback analytics logic
}

function showRecommendations() {
  // Display related recommended content
}

Mobile-Specific Handling

Mobile browsers often restrict autoplay, requiring special handling:

// Detect if autoplay is allowed
video.onplay = () => {
  console.log('Playback started');
};

const playPromise = video.play();

if (playPromise !== undefined) {
  playPromise.catch(error => {
    // Show a play button
    showPlayButton();
  });
}

function showPlayButton() {
  const overlay = document.createElement('div');
  overlay.className = 'play-overlay';
  overlay.onclick = () => {
    video.play();
    overlay.remove();
  };
  document.body.appendChild(overlay);
}

Performance Optimization Tips

  1. Event Throttling: Throttle high-frequency events like timeupdate
let lastUpdate = 0;
video.ontimeupdate = () => {
  const now = Date.now();
  if (now - lastUpdate > 200) {  // Update every 200ms
    updateProgressBar();
    lastUpdate = now;
  }
};
  1. Event Delegation: Use event delegation for multiple media elements
document.addEventListener('play', function(e) {
  if (e.target.tagName === 'VIDEO') {
    // Handle all video play events
  }
}, true);
  1. Memory Management: Remove unnecessary event listeners
function setupPlayer() {
  video.onplay = handlePlay;
}

function teardownPlayer() {
  video.onplay = null;
}

Browser Compatibility Practices

Handling event differences across browsers:

// Check if autoplay is possible
function checkAutoPlay() {
  const promise = video.play();
  if (promise !== undefined) {
    promise.catch(() => {
      // Handle older browsers
      video.muted = true;
      video.play();
    }).then(() => {
      // Handle newer browsers
      if (video.muted) {
        showUnmuteButton();
      }
    });
  }
}

// Unified event handling
const events = ['play', 'playing', 'waiting', 'pause'];
events.forEach(event => {
  video.addEventListener(event, handleAllEvents);
});

Advanced Application Scenarios

Picture-in-Picture Mode Control

video.onenterpictureinpicture = () => {
  console.log('Entered Picture-in-Picture mode');
  updatePiPControls(true);
};

video.onleavepictureinpicture = () => {
  console.log('Exited Picture-in-Picture mode');
  updatePiPControls(false);
};

function updatePiPControls(isInPiP) {
  pipBtn.classList.toggle('active', isInPiP);
}

Media Session API Integration

video.onplay = () => {
  if ('mediaSession' in navigator) {
    navigator.mediaSession.playbackState = 'playing';
    navigator.mediaSession.setActionHandler('pause', () => {
      video.pause();
    });
  }
};

WebRTC Stream Handling

const stream = await navigator.mediaDevices.getUserMedia({video: true});
const video = document.createElement('video');
video.srcObject = stream;

video.onplay = () => {
  console.log('Camera video stream started');
  startFaceDetection();
};

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.