TheWidlarzGroup / react-native-video

A <Video /> component for react-native
https://docs.thewidlarzgroup.com/react-native-video/
MIT License
7.21k stars 2.9k forks source link

Error Playing HLS streams on some devices #1598

Closed paschaldev closed 4 years ago

paschaldev commented 5 years ago

Current behavior

An attempt to play a 1920 resolution HLS stream on devices with lesser pixel fails. This is understandable but is it possible to fallback to the closest supportable resolution. I get this error:

D/MediaCodecInfo: NoSupport [sizeAndRate.support, 3840x1920x-1.0] [OMX.MTK.VIDEO.DECODER.AVC, video/avc] [TECNO-CX-Air, TECNO CX Air, TECNO, 24]

Reproduction steps

Load a 4K HLS stream on a non 4k device.

Expected behavior

Fallback to the nearest possible supported streams in the videoTracksgotten onLoad

Platform

Which player are you experiencing the problem on:

Video sample

This is the stream I used: https://bitmovin-a.akamaihd.net/content/playhouse-vr/m3u8s/105560.m3u8

paschaldev commented 5 years ago

For anyone who stumbled upon this, I was able to get the device's maximum pixels and compare with the HLS videoTracks.

import React from 'react'
import {PixelRatio} from 'react-native'

import _filter from 'lodash/filter'

const DEVICE_HEIGHT = Dimensions.get('window').height
const DEVICE_WIDTH = Dimensions.get('window').width
const PIXEL_RATIO_HEIGHT = PixelRatio.getPixelSizeForLayoutSize(DEVICE_HEIGHT)
const PIXEL_RATIO_WIDTH = PixelRatio.getPixelSizeForLayoutSize(DEVICE_WIDTH)

class Player extends React.Component {
   onVideoLoad(e) {
        const supportedVideoTracks = this.getSupportedStreams(e.videoTracks)
        this.startStream(e, supportedVideoTracks)
    }

   /**
     * Get supported video tracks from the list of tracks defined
     * 
     * @param array videoTracks 
     */
    getSupportedStreams (videoTracks) {

        // Loop through the available tracks and filter only item this device supports
        let tracks = _filter(videoTracks, (track) => {
            // Check if device pixel width and height is more than the track's
            return PIXEL_RATIO_WIDTH >= track.width && PIXEL_RATIO_HEIGHT >= track.height
        })

        return tracks
    }
}

Now I need to still support Adaptive Bitrate streaming and scraping unsupported videos but looks like this library doesn't allow that yet. ABR would pick fro all the videoTracks. No way to pass list of tracks for the ABR.

vladpuz commented 3 years ago

what is this.startStream ?

paschaldev commented 3 years ago

@vladislav-puzyrev It's a custom function I wrote