player icon indicating copy to clipboard operation
player copied to clipboard

Fix: Resolve AirPlay Availability Issues by Enabling Remote Playback

Open DimaDemchenko opened this issue 1 year ago • 3 comments

Related:

closes https://github.com/vidstack/player/issues/1522

Description:

In the Hls.js repository, there are lines of code that remove video sources and set disableRemotePlayback to true.

In your vidstack/player code, I found only appending sources after attaching an element to the Hls.js instance. However, there's no code to set disableRemotePlayback to false after this attachment.

Impact: Not setting disableRemotePlayback to false disrupts the logic when watching the availability of AirPlay state. When disableRemotePlayback is true, watchAvailability throws an error indicating an invalid state, and the support flag remains false. Consequently, the AirPlay button does not appear.

Additional Note: There's another issue with AirPlay functionality: to work correctly on iOS with Hls.js, the video element must have autoplay set to true. Without it, AirPlay doesn't function as expected. This might be an issue with iOS itself.

this.#video.disableRemotePlayback = false;
this.#video.autoplay = true;

Ready?

The provided code resolves the issue by allowing the remote playback API to accurately detect AirPlay availability. However, I recommend integrating this fix in a more appropriate location within the codebase to maintain code quality and consistency. Additionally, addressing the autoplay requirement for iOS should be considered, potentially as a separate issue.

Anything Else?

https://github.com/video-dev/hls.js/issues/6482

DimaDemchenko avatar Jan 13 '25 14:01 DimaDemchenko

Hello, is there any way to set this.#video.disableRemotePlayback = false; in react?

daoudeddy avatar Jan 21 '25 11:01 daoudeddy

Hello, is there any way to set this.#video.disableRemotePlayback = false; in react?

import "@vidstack/react/player/styles/default/theme.css";
import "@vidstack/react/player/styles/default/layouts/video.css";
import {
  MediaPlayer,
  MediaProvider,
  isHLSProvider,
  type MediaProviderAdapter,
} from "@vidstack/react";
import {
  defaultLayoutIcons,
  DefaultVideoLayout,
} from "@vidstack/react/player/layouts/default";
import Hls from "hls.js";

export const HlsjsVidstack = () => {
  const onProviderChange = (provider: MediaProviderAdapter | null) => {
    class extendedHls extends Hls {
      attachMedia(media: HTMLMediaElement): void {
        super.attachMedia(media);

        media.disableRemotePlayback = false;
        media.autoplay = true;
      }
    }
    if (isHLSProvider(provider)) {
      provider.library = extendedHls;
    }
  };

  return (
    <div>
      <MediaPlayer
        autoPlay
        muted
        onProviderChange={onProviderChange}
        src={"https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"}
        playsInline
      >
        <MediaProvider />
        <DefaultVideoLayout icons={defaultLayoutIcons} />
      </MediaPlayer>
    </div>
  );
};

DimaDemchenko avatar Jan 21 '25 15:01 DimaDemchenko

Hello, is there any way to set this.#video.disableRemotePlayback = false; in react?

import "@vidstack/react/player/styles/default/theme.css";
import "@vidstack/react/player/styles/default/layouts/video.css";
import {
  MediaPlayer,
  MediaProvider,
  isHLSProvider,
  type MediaProviderAdapter,
} from "@vidstack/react";
import {
  defaultLayoutIcons,
  DefaultVideoLayout,
} from "@vidstack/react/player/layouts/default";
import Hls from "hls.js";

export const HlsjsVidstack = () => {
  const onProviderChange = (provider: MediaProviderAdapter | null) => {
    class extendedHls extends Hls {
      attachMedia(media: HTMLMediaElement): void {
        super.attachMedia(media);

        media.disableRemotePlayback = false;
        media.autoplay = true;
      }
    }
    if (isHLSProvider(provider)) {
      provider.library = extendedHls;
    }
  };

  return (
    <div>
      <MediaPlayer
        autoPlay
        muted
        onProviderChange={onProviderChange}
        src={"https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"}
        playsInline
      >
        <MediaProvider />
        <DefaultVideoLayout icons={defaultLayoutIcons} />
      </MediaPlayer>
    </div>
  );
};

Thank you.

daoudeddy avatar Jan 21 '25 18:01 daoudeddy