Disabling Audio Tracks in HLS.js

CK CK 3788 
Created at  
387 0 0

I had a case to disable audio tracks when the app played back the HLS video stream. The initial approach I tried was to mute the sound, but the problem was that the user could turn it on any time.

The best method to disable audio tracks in HLS.js, rather than simply muting them, involves manipulating the audioTracks property of the HLS instance. Here's a breakdown of the process and considerations:

 

Understanding audioTracks and enabled

HLS.js exposes an audioTracks array on its instance. Each element in this array represents a distinct audio rendition (e.g., different languages or qualities) available in the HLS stream. Crucially, each audio track object has an enabled property:

  • audioTrack.enabled = true; Indicates the audio track is active and will be played.
  • audioTrack.enabled = false; Indicates the audio track is inactive and will not be played. This is what you want to achieve disabling, not muting.

Disabling Audio Tracks in HLS.js

Code Example

import Hls from 'hls.js';

// Assume you have a valid HLS stream URL:
const videoSrc = 'your_hls_stream_url.m3u8';

// Get your video element (make sure it's in the DOM)
const video = document.getElementById('yourVideoElement');

if (Hls.isSupported()) {
  const hls = new Hls();

  hls.on(Hls.Events.MANIFEST_PARSED, () => {
    // Access the audio tracks after the manifest has been parsed
    const audioTracks = hls.audioTracks;

    // Disable all audio tracks *except* for the desired one (e.g., the first one).
    // Modify the logic as needed based on your requirements.
    for (let i = 0; i < audioTracks.length; i++) {
      audioTracks[i].enabled = (i === 0); // Enable only the first track
      //Alternatively:  audioTracks[i].enabled = (audioTracks[i].name === "English"); //Enable track named English
    }

    // Or, to disable *all* audio tracks:
    // audioTracks.forEach(track => track.enabled = false);
  });

  hls.loadSource(videoSrc);
  hls.attachMedia(video);
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
  // Native HLS support (e.g., Safari)
  video.src = videoSrc;
} else {
  console.error('HLS is not supported in this browser.');
}

Explanation

1. Import HLS.js: import Hls from 'hls.js';
2. Initialize HLS: Create an instance of Hls.
3. MANIFEST_PARSED Event: This is the critical step. You must wait for the MANIFEST_PARSED event to fire. This event signifies that HLS.js has finished parsing the HLS manifest (the .m3u8 file) and has discovered the available audio tracks. Trying to access hls.audioTracks before this event will result in an empty or undefined array.
4. Access audioTracks: Inside the MANIFEST_PARSED event handler, access hls.audioTracks.
5. Iterate and Disable (or Enable Selectively):

  • Disable All (Except One): The example loops through the audioTracks array and sets audioTracks[i].enabled = false; for each track you want to disable. The code in the example enables only the first one. Adapt the condition (i === 0) to match your needs (e.g., check the audioTracks[i].name property if you know the name of the desired track).
  • Disable All: Use audioTracks.forEach(track => track.enabled = false); to disable every track.

6. Load and Attach: hls.loadSource(videoSrc); loads the HLS stream, and hls.attachMedia(video); attaches the HLS instance to your  element.

 

Important Considerations and Best Practices

  • Event Timing: Always work with audioTracks within the MANIFEST_PARSED event. This is the single most common source of errors when trying to manipulate audio tracks.
  • Track Identification: You need a way to identify the audio track(s) you want to disable. Common properties to use are:
    • audioTrack.id: A unique ID assigned to the track. Less human-readable.
    • audioTrack.name: A human-readable name (e.g., "English", "Spanish", "Commentary").
    • audioTrack.groupId: An id to group different audio tracks together, such as a language selection.
    • audioTrack.lang: The language code (e.g., "en", "es", "fr"). A standard language code.
  • User Interface (UI): Typically, you'd want to provide a UI (e.g., a dropdown or a list of checkboxes) that allows the user to select which audio tracks they want to enable or disable. When the user makes a selection, update the audioTrack.enabled property accordingly.
  • HLS.js Configuration: HLS.js provides many configuration options. While not directly related to disabling audio tracks, reviewing the configuration options can help optimize your player.
  • Muting vs. Disabling:
    • Muting (video.muted = true;): Mutes the entire video element. All audio is silenced. This is a simple approach, but it doesn't let the user choose between audio tracks.
    • Disabling (audioTrack.enabled = false;): Prevents the HLS.js library from even requesting the audio renditions for the disabled track. This is more efficient because it reduces network bandwidth and processing overhead. It's the preferred method for selective audio track control.
  • Adaptive Bitrate (ABR): HLS.js manages adaptive bitrate switching. Disabling an audio track affects which segments are requested from the server, ensuring that only segments for the enabled tracks are downloaded.
  • Error Handling: Implement error handling (using hls.on(Hls.Events.ERROR, ...)). Errors can occur during manifest parsing or segment loading. Proper error handling will make your player more robust.
  • Avoid redundant calls: After enabling/disabling tracks, avoid calling hls.loadSource() or hls.attachMedia() again unless it's truly necessary (e.g., a completely new stream is being loaded).

By using audioTrack.enabled = false;, you are effectively telling HLS.js not to use that audio track. This is the most efficient and correct way to disable audio tracks in HLS.js for a user-controlled experience. Remember to do this within the MANIFEST_PARSED event handler.

Tags Audio Tracks HLS HLS.js Mute auduoTracks Facebook X
Comments 0
Similar posts
  1. Smooth switching with EXT-X-DISCONTINUITY in HLS
    442
  2. When to use #EXT-X-DISCONTINUITY in HLS?
    1,437
  3. Limit Maximum Resolution in HLS.js
    669
  4. Extracting Context from Live Video: The Architecture Got Simpler When We Stopped Building Features
    263
  5. The Next-Gen Low-Latency Standards: LL-HLS & MoQ
    203
  6. Unlock Flawless HLS Audio Sync: The Power of #EXT-X-INDEPENDENT-SEGMENTS
    381
  7. HTTP Live Streaming (HLS) was developed by Apple as part of QuickTime X in iOS3.0, and became an official standard (RFC 8126) in 2017
    597
  8. HLS.js options to support subtitle
    522
  9. When HLS.js need to load m3u8 URL redirecting to the different URL (302 Redirection)
    666
  10. HLS.js code to reload when user face bufferfull error
    706
  11. HLS.js code to reload video when levelLoadTimeOut occurs
    714
  12. Change the manifest loading timeout in HLS.js
    1,046
  13. Mastering Audio Sync: Keyframes, GOP, FFmpeg, and HLS Explained
    548
  14. How do I display trickplay images with hls.js that elaborated at EXT-X-IMAGE-STREAM-INF in m3u8
    812
  1. Inside the Next-Generation Streaming Architecture: Ultra-Low Latency, SGAI, and AI Codecs
    207
  2. From SDI to MXL: Inside the Cloud-Native Infrastructure Powering Next-Gen Live Broadcast
    582
  3. A Deep Dive Into Internet Advertising Ecosystem on Video Streaming Industry
    652
  4. A prefect Apache server settings to avoid CORS error for HLS
    607
  5. CloudFront Settings for Dynamic HLS Streaming
    651
  6. SafeFrame is a web standard developed by IAB
    514
  7. CSAI vs SSAI
    580
  8. Ad Marker: SCTE-35 Message Encoder based in Python
    806
  9. Ad marker: SCTE-35 enhanced
    578
  10. FFmpeg compile options based on configure
    1,120
  11. Script checking internet restriction with FFmpeg
    686
  12. FFmpeg compile option to support SCTE-35
    844
  13. HTTP Proxy when your URL access is blocked with FFmpeg
    1,917
  14. Magic line when HLS video manifest is mixed with encrypted / unencrypted video chunks
    1,481
  15. Recovering a crashed HLS.js player
    1,289
  16. How do I create animated background for Google Meet?
    23,222
  17. Secure HLS encoding using AES-128 encryption with FFmpeg
    1,144
Recently updated
  1. Google OAuth Token Expiration: Causes and Solutions
    31
  2. Why 100% SEO Guarantees Better User Engagement and How to Achieve It in Your Service
    57
  3. Why SPF and DKIM Are Essential for Linux Email Servers?
    51
  4. MaxMind GeoLite2 vs. DB-IP Lite vs. ip-api.com: Choosing the Right Free IP Geolocation Solution
    273
  5. Meet Valkey: Why Redis Changed Its License, Why Valkey is Better, and How to Use It as a Drop-in Replacement
    104
  6. How Rogue Web Scrapers Are Stealing My Content and Destroying My Server
    170
  7. Array of arguments passed to script in PHP
    99
  8. Invalid Auction Storms in Ad Tech
    107
  9. Building MRC-Compliant Instrumentation in Ad Tech: Implementation Steps and Key Challenges
    208
  10. The Two Clocks of Ad Server Architecture
    78
  11. Frequency Cap Architecture Overview
    527
  12. Collecting Proof-of-Play from 100,000 Screens
    153
  13. Vector Search in Relational Databases (RDBs): Trends & Usage Environments
    303
  14. What is RedisVL?
    116
  15. Designing a Skill Registry Architecture: Minimize Token Usage and Maximize AI Performance
    247
  16. TPU & GPU Cluster Management Tools
    258
  17. The Concept of Scaffolding in AI Agents
    245
  18. Beyond Static Pipelines: Architecting LLM Multi-Agent Systems for Autonomous Workflow Orchestration
    598
  19. AI-DLC vs. AI-SDLC: Model-Centric vs. System-Centric AI Development
    268
  20. Fine-Tuning Open-Weight LLMs: Training, Licensing, and Deploying Custom Models with Ollama
    354
  21. Machine Learning: Training vs. Ranking
    230
  22. The Continuous Learning Machine: Designing a Loop That Actually Turns
    228
  23. Designing a Data Curation System Around a Vector Database
    230
  24. The New Ad Stack Behind Live Sports Streaming: Inside SGAI, EABN, and the Standards Race to Fix Live Monetization
    674
  25. Designing MLOps Architectures to Handle Seasonal Data Drift in EV Fleet Models
    201
  26. From 15 to 40+ FPS: Accelerating PyTorch Object Detection on Automotive ECUs
    233
  27. Understanding Data Lineage
    272
  28. System Requirements and Architecture: Intelligent Priority-Based Scheduler
    176
  29. GPU & LLM Cluster Infrastructure & Task Scheduling Architecture
    255
  30. Java Variant Type
    212