Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Safari Compatibility on macOS? #3

Open
chrisspiegl opened this issue Sep 10, 2023 · 8 comments
Open

Safari Compatibility on macOS? #3

chrisspiegl opened this issue Sep 10, 2023 · 8 comments

Comments

@chrisspiegl
Copy link

Just tried this (as mentioned before).
Found this potential bug when opening a site with the video player in Safari on macOS.

Xnapper-2023-09-10-17 21 16

Basically, in a Chromium based browser it works. But in Safari it does not show?

@tomexsans
Copy link
Owner

Hello thanks for submitting.

I'll try to look into it, i currently have no access to Any MAC.

I'm only relying on UI Tests which turn out did not catch.

Could you add here the Version of Safari and MacOS you are using?

@chrisspiegl
Copy link
Author

Sure thing. I understand. I will be available to test any code commits if you have any.

Safari Version: Version 17.0 (19616.1.27.111.16)
macOS: 14.0 Beta (23A5337a) (Sanoma)

@tomexsans tomexsans pinned this issue Sep 28, 2023
@cbarburescu
Copy link

cbarburescu commented Oct 26, 2023

Hi,

For me, it works on Safari - MacOS Ventura 13.4 - if I set overrideNative to true from videojs' options: https://github.com/videojs/http-streaming#overridenative (without it, it looks the same as in your screenshot @chrisspiegl)

However, I have the same problem on multiple browsers (Chrome, Firefox, Safari) on iPhone (iOS 16.6.1) and the setting above does not fix it.

Does anyone have any ideas?

Thank you!

@chrisspiegl
Copy link
Author

The overrideNative: true does appear to change a lot and is very useful in this scenario. I also have found this.

And I was able to get it to work on Desktop (Chrome, Safari), Android, Safari, and iPhone (when using the appropriate plugins and setting the overrideNative: true).

However, to be honest, at the end of the day, I actually chose to keep overrideNative but disable the quality selector for now and just rely on the system to give me the best quality that the internet connection can handle.

@cbarburescu
Copy link

Thanks for responding @chrisspiegl. Do you remember what you settings/ plugins did you use for iPhone in order to have a select quality button?

@chrisspiegl
Copy link
Author

Hi @cbarburescu ,

I put together a bit of a gist about the code that I am using. It is a bit of an excerpt though.

  • So far, I have tested this code in Chrome and in Safari on macOS.
  • I will keep testing it on other devices once I deployed to my staging environment.

Obviously, the css also needs to be included and the whole vue component wrapped around it all. That is not included in the code below and I will not have time to build a CodeSandbox anytime soon 🙈.

But I hope this helps to document what works and maybe find more settings to add / change.

Devices to be tested:

  • Android Phone
  • iPad
  • iPhone

Code Excerpt to run Video.JS Player

import type Player from 'video.js/dist/types/player'
import type { QualityLevel } from 'videojs-contrib-quality-levels'
import qualitySelector from 'videojs-quality-selector-hls'
import videojs from 'video.js'
import consola from 'consola'

interface CustomPlayer extends Player {
  [key: string]: any
}

const logger = consola.withTag('VideoFileEmbedPlayer')

const player = ref<CustomPlayer | undefined>(undefined)
const videoElement = ref()

onMounted(async () => {
  if (!videojs.getPlugin('qualitySelector')) {
    logger.log('🚧 register qualitySelector')
    videojs.registerPlugin('qualitySelector', qualitySelector)
  }

  
  player.value = videojs(videoElement.value, {
    qualityLevels: true,
    aspectRatio: '16:9',
    autoplay: false,
    preload: false,
    fluid: true,
    controlBar: {
      playToggle: {
        replay: false,
      },
      volumePanel: {
        inline: true,
      },
      currentTimeDisplay: true,
      timeDivider: true,
      durationDisplay: true,
      progressControl: true,
      remainingTimeDisplay: false,
      playbackRateMenuButton: true,
      qualitySelector: true, // Quality selector should show up
      fullscreenToggle: true,

      liveDisplay: false,
      customControlSpacer: false,
      chaptersButton: false,
      descriptionsButton: false,
      subtitlesButton: false,
      captionsButton: false,
      subsCapsButton: false,
      audioTrackButton: false,
      pictureInPictureToggle: true,
    },
    controls: true,
    playbackRates: [0.5, 0.75, 1, 1.25, 1.5, 2, 2.5, 3],
    loop: false,
    volume: 1,
    html5: {
      // VHS has to be present for Safari (macOS) to pic up the video stream.
      vhs: {
        useDevicePixelRatio: true,
        // NOTE: The NetworkInformationAPI appears to make things higher quality on Safari.
        useNetworkInformationApi: true,
        // NOTE: this overrides the native HLS support for Safari which in turn activates the ability to more finely control the resolutions available and logging to console.
        // This can be deactivated and it will use the quality level appropriate for the internet speed, screen resolution, pixel density.
        overrideNative: true, // this makes it possible for videojs to overtake the quality selection (could use overrideNative: !videojs.browser.IS_SAFARI)
      },
      hls: {
        useDevicePixelRatio: true,
        // NOTE: The NetworkInformationAPI appears to make things higher quality on Safari.
        useNetworkInformationApi: true,
        // NOTE: this overrides the native HLS support for Safari which in turn activates the ability to more finely control the resolutions available and logging to console.
        // This can be deactivated and it will use the quality level appropriate for the internet speed, screen resolution, pixel density.
        overrideNative: true, // this makes it possible for videojs to overtake the quality selection (could use overrideNative: !videojs.browser.IS_SAFARI)
      },
      // These two also did something which I don't remember, I think Android devices had problems when this was set to true.
      nativeAudioTracks: false,
      nativeVideoTracks: false,
      // nativeTextTracks: false,
    },
    sources: [{
      src: 'https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8',
      type: 'application/x-mpegURL',
    }],
  }, async () => {
    if (!player.value) {
      logger.error('Player should have been ready but wasn\'t!')
      return
    }
    logger.log('Video Player Ready')
    
    // Activate Quality Selector
    player.value.qualitySelectorHls({
      displayCurrentQuality: true, // makes it display the quality level in text form vs. false => displays a icon.
      // placementIndex: 2,
      vjsIconClass: 'vjs-icon-hd',
    })

    // Add some logging to see if the video.js player even has information about quality levels
    const qualityLevels = player.value.qualityLevels()
    player.value.qualityLevels().on('addqualitylevel', (data: { qualityLevel: QualityLevel }) => {
      logger.log('📺 M3U8 playlist is loaded!', `${data.qualityLevel.height}p`, `${data.qualityLevel.bitrate / 1000} kB/s`)
    })
    player.value.qualityLevels().on('change', () => {
      logger.log('📺 Quality Level changed! New level:', qualityLevels[qualityLevels.selectedIndex])
    })
  })
})

@minna-no-jihye
Copy link

Hi Mr @chrisspiegl
Have you conducted the test in the 'Fairplay DRM environment' as well? When overrideNative is set to true, this setting cannot be used because the webkitneedkey is not triggered.

@chrisspiegl
Copy link
Author

@minna-no-jihye: I have not worked with any DRM type things. So, so I do not know anything about this.

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

No branches or pull requests

4 participants