Skip to content

Conversation

@cotid-qualabs
Copy link

No description provided.

@gemini-code-assist
Copy link

Summary of Changes

Hello @cotid-qualabs, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request adds a new interactive sample page to demonstrate DASH.js's ability to manage live-to-live alternative media presentations. The sample provides a user-friendly interface for configuring and testing dynamic 'replace events' within a live streaming context, allowing users to define when and how an alternative live stream should temporarily replace the main live stream. This enhancement helps showcase advanced live streaming capabilities and provides a practical tool for developers to experiment with alternative content switching.

Highlights

  • New Sample Page: Introduced a new sample page, live-to-live.html, demonstrating live-to-live alternative media presentations with dynamic content switching in DASH streams.
  • Dynamic Event Configuration: The sample includes a user interface to configure 'replace events' dynamically, allowing users to specify main and alternative live stream URLs, time offsets, durations, return offsets, max durations, and options for clipping and starting at playhead.
  • Manifest Event Injection: Implemented JavaScript logic to dynamically generate and inject EventStream elements with ReplacePresentation events into the DASH manifest based on user-defined configurations.
  • Samples Index Update: Updated samples/samples.json to include the new live-to-live sample and organize it under a dedicated 'Alternative Media Presentations' section.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new sample page for live-to-live alternative media presentations. The implementation is well-structured, but I've identified a few areas for improvement concerning JavaScript best practices, code quality, and security. Specifically, there's a potential Cross-Site Scripting (XSS) vulnerability in the manifest viewer that should be addressed. I've also included suggestions to refactor the event display logic for better maintainability and to clean up some redundant code in the initialization function.

Comment on lines +256 to +271
let highlighted = manifestXml
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/(&lt;\/?)(\w+)(.*?)(\/?&gt;)/g, (match, open, tagName, attrs, close) => {
let isAltMpd = (tagName === "ReplacePresentation");
let coloredTag = `<span class="token.tag${isAltMpd ? ' token.altmpd' : ''}">${open}${tagName}</span>`;
if (attrs.trim().length > 0) {
attrs = attrs.replace(/(\w+)="(.*?)"/g, `<span class="token.attr-name">$1</span>="<span class="token.attr-value">$2</span>"`);
coloredTag += attrs;
}
coloredTag += `<span class="token.tag${isAltMpd ? ' token.altmpd' : ''}">${close}</span>`;
return coloredTag;
});

viewer.innerHTML = highlighted;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The updateManifestViewer function is vulnerable to Cross-Site Scripting (XSS). It constructs HTML using innerHTML and includes user-provided data from the 'Alternative Live Stream URL' input field. The regex-based syntax highlighting does not properly sanitize attribute values, allowing a malicious user to inject arbitrary HTML attributes and event handlers (e.g., onmouseover). For example, an input like http://a.com" onmouseover="alert('XSS') would result in executable JavaScript.

To fix this, you should avoid building HTML with string concatenation. Instead, create DOM elements programmatically and set user-provided content using textContent to ensure it's treated as plain text.

Comment on lines +152 to +154
var video = document.getElementById('video-element');
var alternativeVideo = document.getElementById('alternative-video-element');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The variables video and alternativeVideo are declared but never used within the init function. They are retrieved again later in the loadPlayer function. To improve code clarity and avoid redundancy, these unused variable declarations should be removed. Additionally, var is used here, while the rest of the code uses let and const. Removing these lines will also improve consistency.

Comment on lines +218 to +225
eventDiv.innerHTML = `
<div>
<strong>Replace Event #${event.id + 1}</strong><br>
<small>Time: ${timeString} (${event.timeOffset}s from now)<br>
Duration: ${event.duration}ms | Return Offset: ${event.returnOffset}ms</small>
</div>
<button class="btn btn-sm btn-danger" onclick="removeEvent(${index})">Remove</button>
`;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using innerHTML with an inline onclick event handler is not a recommended practice. It couples the HTML tightly with the JavaScript logic, can be blocked by Content Security Policies (CSP), and requires the removeEvent function to be globally accessible. A better approach is to create the elements programmatically using document.createElement and attach event listeners using addEventListener. This makes the code cleaner, safer, and more compliant with modern web standards.

Suggested change
eventDiv.innerHTML = `
<div>
<strong>Replace Event #${event.id + 1}</strong><br>
<small>Time: ${timeString} (${event.timeOffset}s from now)<br>
Duration: ${event.duration}ms | Return Offset: ${event.returnOffset}ms</small>
</div>
<button class="btn btn-sm btn-danger" onclick="removeEvent(${index})">Remove</button>
`;
const detailsDiv = document.createElement('div');
detailsDiv.innerHTML = `<strong>Replace Event #${event.id + 1}</strong><br>
<small>Time: ${timeString} (${event.timeOffset}s from now)<br>
Duration: ${event.duration}ms | Return Offset: ${event.returnOffset}ms</small>`;
const removeButton = document.createElement('button');
removeButton.className = 'btn btn-sm btn-danger';
removeButton.textContent = 'Remove';
removeButton.addEventListener('click', () => removeEvent(index));
eventDiv.append(detailsDiv, removeButton);

@sebastianpiq sebastianpiq merged commit b68b73f into feature/alternative-media-presentations Oct 8, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants