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

Some streams are not loading #1611

Closed
theScrabi opened this issue Aug 18, 2018 · 11 comments
Closed

Some streams are not loading #1611

theScrabi opened this issue Aug 18, 2018 · 11 comments
Labels
bug Issue is related to a bug

Comments

@theScrabi
Copy link
Member

theScrabi commented Aug 18, 2018

For some streams some resolution is never loading.
Take this one here for example:
https://www.youtube.com/watch?v=00Q4SUnVQK4
If you select 480p you will see the Loading cycle cycle forever.

This is the coresponding logcat output:

08-18 13:02:10.122 21561-21561/org.schabi.newpipe.debug D/SerializedCache: put() called with: key = [1e67ab85-b83a-4ce0-9209-faebf74146c1], item = [org.schabi.newpipe.player.playqueue.SinglePlayQueue@6efad41]
    
    --------- beginning of system
08-18 13:02:10.137 21561-21561/org.schabi.newpipe.debug D/.MainVideoPlayer: onCreate() called with: savedInstanceState = [null]
    hideSystemUi() called
08-18 13:02:10.167 21561-21561/org.schabi.newpipe.debug D/BasePlayer: initPlayer() called with: context = [org.schabi.newpipe.player.MainVideoPlayer@52748be]
08-18 13:02:10.168 21561-21561/org.schabi.newpipe.debug I/ExoPlayerImpl: Init b3246d2 [ExoPlayerLib/2.8.2] [generic_x86, Android SDK built for x86, Google, 27]
08-18 13:02:10.168 21561-21561/org.schabi.newpipe.debug D/BasePlayer: ExoPlayer - onPlayerStateChanged() called with: playWhenReady = [true], playbackState = [1]
08-18 13:02:10.171 21561-21561/org.schabi.newpipe.debug D/BasePlayer: handleIntent() called with: intent = [Intent { flg=0x10000000 cmp=org.schabi.newpipe.debug/org.schabi.newpipe.player.MainVideoPlayer (has extras) }]
08-18 13:02:10.171 21561-21561/org.schabi.newpipe.debug D/SerializedCache: take() called with: key = [1e67ab85-b83a-4ce0-9209-faebf74146c1]
08-18 13:02:10.171 21561-21561/org.schabi.newpipe.debug D/BasePlayer: destroyPlayer() called
08-18 13:02:10.172 21561-21561/org.schabi.newpipe.debug I/ExoPlayerImpl: Release b3246d2 [ExoPlayerLib/2.8.2] [generic_x86, Android SDK built for x86, Google, 27] [goog.exo.core, goog.exo.mediasession]
08-18 13:02:10.173 21561-21561/org.schabi.newpipe.debug D/BasePlayer: initPlayer() called with: context = [org.schabi.newpipe.player.MainVideoPlayer@52748be]
08-18 13:02:10.173 21561-21561/org.schabi.newpipe.debug I/ExoPlayerImpl: Init 21c7259 [ExoPlayerLib/2.8.2] [generic_x86, Android SDK built for x86, Google, 27]
08-18 13:02:10.174 21561-21561/org.schabi.newpipe.debug D/BasePlayer: ExoPlayer - onPlayerStateChanged() called with: playWhenReady = [true], playbackState = [1]
08-18 13:02:10.176 21561-21561/org.schabi.newpipe.debug D/PlayQueue@6efad41: Received broadcast: INIT. Current index: 0, play queue length: 1.
08-18 13:02:10.179 21561-21561/org.schabi.newpipe.debug D/.MainVideoPlayer: onResume() called
08-18 13:02:10.192 21561-21561/org.schabi.newpipe.debug E/RecyclerView: No adapter attached; skipping layout
08-18 13:02:10.207 21561-21561/org.schabi.newpipe.debug D/MediaSourceManager@181009950: maybeBlock() called.
08-18 13:02:10.207 21561-21561/org.schabi.newpipe.debug D/BasePlayer: Playback - onPlaybackBlock() called
08-18 13:02:10.208 21561-21561/org.schabi.newpipe.debug D/BasePlayer: changeState() called with: state = [123]
    onBlocked() called
08-18 13:02:10.208 21561-21561/org.schabi.newpipe.debug D/AnimationUtils: animateView()   false →  [RelativeLayout:playbackControlRoot] [ALPHA 300:0] execOnEnd=null
    animateView() view was already gone > view = [android.widget.RelativeLayout{8391391 G.E...... ......I. 0,0-0,0 #7f09017f app:id/playbackControlRoot}]
08-18 13:02:10.209 21561-21561/org.schabi.newpipe.debug D/AnimationUtils: animateView()    true →  [RelativeLayout:loading_panel] [ALPHA 0:0] execOnEnd=null
    animateView() view was already visible > view = [android.widget.RelativeLayout{769b2f6 V.E...... ......ID 0,0-1080,1920 #7f09011d app:id/loading_panel}]
08-18 13:02:10.210 21561-21561/org.schabi.newpipe.debug D/AnimationUtils: animateView()    true →  [View:surfaceForeground] [ALPHA 100:0] execOnEnd=null
    animateView() view was already visible > view = [android.view.View{ccc56f7 V.ED..... ......ID 0,0-1080,1920 #7f0901eb app:id/surfaceForeground}]
    animateView()   false →  [AppCompatImageButton:playPauseButton] [SCALE_AND_ALPHA 100:0] execOnEnd=null
08-18 13:02:10.211 21561-21561/org.schabi.newpipe.debug D/AnimationUtils: animateView()   false →  [AppCompatImageButton:playPreviousButton] [SCALE_AND_ALPHA 100:0] execOnEnd=null
    animateView()   false →  [AppCompatImageButton:playNextButton] [SCALE_AND_ALPHA 100:0] execOnEnd=null
08-18 13:02:10.211 21561-21561/org.schabi.newpipe.debug D/MediaSourceManager@181009950: resetSources() called.
08-18 13:02:10.212 21561-21561/org.schabi.newpipe.debug D/MediaSourceManager@181009950: populateSources() called.
    MediaSource - loadImmediate() called
    MediaSource - maybeClearLoaders() called.
    maybeLoadItem() called.
    MediaSource - Loading=[Hitze extrem - Windhose in TBB] with url=[https://www.youtube.com/watch?v=00Q4SUnVQK4]
08-18 13:02:10.212 21561-21618/org.schabi.newpipe.debug D/InfoCache: getFromKey() called with: serviceId = [0], url = [https://www.youtube.com/watch?v=00Q4SUnVQK4]
08-18 13:02:10.212 21561-21618/org.schabi.newpipe.debug D/ExtractorHelper: loadFromCache() called, info > StreamInfo[url="https://www.youtube.com/watch?v=00Q4SUnVQK4", name="Hitze extrem - Windhose in TBB"]
08-18 13:02:10.218 21561-21592/org.schabi.newpipe.debug D/EGL_emulation: eglMakeCurrent: 0x97fff9a0: ver 2 0 (tinfo 0xa62bff80)
08-18 13:02:10.227 21561-21592/org.schabi.newpipe.debug D/EGL_emulation: eglMakeCurrent: 0x97fff9a0: ver 2 0 (tinfo 0xa62bff80)
08-18 13:02:10.229 21561-21592/org.schabi.newpipe.debug D/EGL_emulation: eglMakeCurrent: 0x97fff9a0: ver 2 0 (tinfo 0xa62bff80)
08-18 13:02:10.236 21561-21592/org.schabi.newpipe.debug D/EGL_emulation: eglMakeCurrent: 0x97fff9a0: ver 2 0 (tinfo 0xa62bff80)
08-18 13:02:10.236 21561-21561/org.schabi.newpipe.debug D/MediaSourceManager@181009950: MediaSource - Loaded=[Hitze extrem - Windhose in TBB] with url=[https://www.youtube.com/watch?v=00Q4SUnVQK4]
    MediaSource - Updating index=[0] with title=[Hitze extrem - Windhose in TBB] at url=[https://www.youtube.com/watch?v=00Q4SUnVQK4]
08-18 13:02:10.237 21561-21561/org.schabi.newpipe.debug D/MediaSourceManager@181009950: maybeUnblock() called.
08-18 13:02:10.237 21561-21561/org.schabi.newpipe.debug D/BasePlayer: Playback - onPlaybackUnblock() called
    changeState() called with: state = [125]
08-18 13:02:10.237 21561-21561/org.schabi.newpipe.debug D/VideoPlayerImpl.MainVideoPlayer: onBuffering() called
08-18 13:02:10.237 21561-21561/org.schabi.newpipe.debug D/BasePlayer: ExoPlayer - onPlayerStateChanged() called with: playWhenReady = [true], playbackState = [2]
08-18 13:02:10.237 21561-21561/org.schabi.newpipe.debug D/MediaSourceManager@181009950: maybeSync() called.
08-18 13:02:10.237 21561-21561/org.schabi.newpipe.debug D/BasePlayer: Playback - onPlaybackSynchronize() called with item=[Hitze extrem - Windhose in TBB], url=[https://www.youtube.com/watch?v=00Q4SUnVQK4]
    Playback - Rewinding to correct index=[0], from=[0], size=[0].
08-18 13:02:10.238 21561-21561/org.schabi.newpipe.debug D/BasePlayer: ExoPlayer - onPositionDiscontinuity() called with reason = [1]
08-18 13:02:10.242 21561-21592/org.schabi.newpipe.debug D/EGL_emulation: eglMakeCurrent: 0x97fff9a0: ver 2 0 (tinfo 0xa62bff80)
08-18 13:02:10.244 21561-21592/org.schabi.newpipe.debug I/chatty: uid=10080(org.schabi.newpipe.debug) RenderThread identical 1 line
08-18 13:02:10.247 21561-21592/org.schabi.newpipe.debug D/EGL_emulation: eglMakeCurrent: 0x97fff9a0: ver 2 0 (tinfo 0xa62bff80)
08-18 13:02:10.247 21561-21592/org.schabi.newpipe.debug D/OpenGLRenderer: endAllActiveAnimators on 0x9813be00 (FrameLayout) with handle 0x95b7f150
08-18 13:02:10.249 21561-21645/org.schabi.newpipe.debug D/CacheFactory: initExoPlayerCache: cacheDir = /storage/emulated/0/Android/data/org.schabi.newpipe.debug/cache/exoplayer
    initExoPlayerCache: cacheDir = /storage/emulated/0/Android/data/org.schabi.newpipe.debug/cache/exoplayer
08-18 13:02:10.252 21561-21561/org.schabi.newpipe.debug D/BasePlayer: ExoPlayer - onTimelineChanged() called with no manifest, timeline size = [1], reason = [0]
    Playback - onMetadataChanged() called, playing: Hitze extrem - Windhose in TBB
    Thumbnail - initThumbnail() called
    Thumbnail - onLoadingStarted() called on: imageUri = [https://i.ytimg.com/vi/00Q4SUnVQK4/hqdefault.jpg], view = [null]
    Thumbnail - onLoadingComplete() called with: imageUri = [https://i.ytimg.com/vi/00Q4SUnVQK4/hqdefault.jpg], view = [null], loadedImage = [android.graphics.Bitmap@68c5d3b]
08-18 13:02:10.258 21561-21561/org.schabi.newpipe.debug D/BasePlayer: ExoPlayer - onSeekProcessed() called
08-18 13:02:10.259 21561-21561/org.schabi.newpipe.debug D/BasePlayer: ExoPlayer - onLoadingChanged() called with: isLoading = [true]
08-18 13:02:10.261 21561-21592/org.schabi.newpipe.debug D/EGL_emulation: eglMakeCurrent: 0x97fff9a0: ver 2 0 (tinfo 0xa62bff80)
08-18 13:02:10.579 21561-21561/org.schabi.newpipe.debug E/RecyclerView: No adapter attached; skipping layout
08-18 13:02:10.622 21561-21566/org.schabi.newpipe.debug I/zygote: Do full code cache collection, code=498KB, data=310KB
08-18 13:02:10.624 21561-21566/org.schabi.newpipe.debug I/zygote: After code cache collection, code=497KB, data=266KB
08-18 13:02:12.578 21561-21561/org.schabi.newpipe.debug D/MediaSourceManager@181009950: MediaSource - loadImmediate() called
08-18 13:02:12.579 21561-21561/org.schabi.newpipe.debug D/MediaSourceManager@181009950: MediaSource - maybeClearLoaders() called.
    maybeLoadItem() called.
08-18 13:02:14.578 21561-21561/org.schabi.newpipe.debug D/MediaSourceManager@181009950: MediaSource - loadImmediate() called
    MediaSource - maybeClearLoaders() called.
    maybeLoadItem() called.
08-18 13:02:16.572 21561-21566/org.schabi.newpipe.debug I/zygote: Do partial code cache collection, code=497KB, data=268KB
    After code cache collection, code=497KB, data=268KB
    Increasing code cache capacity to 2MB
08-18 13:02:16.578 21561-21561/org.schabi.newpipe.debug D/MediaSourceManager@181009950: MediaSource - loadImmediate() called
08-18 13:02:16.579 21561-21561/org.schabi.newpipe.debug D/MediaSourceManager@181009950: MediaSource - maybeClearLoaders() called.
    maybeLoadItem() called.
08-18 13:02:18.578 21561-21561/org.schabi.newpipe.debug D/MediaSourceManager@181009950: MediaSource - loadImmediate() called
    MediaSource - maybeClearLoaders() called.
    maybeLoadItem() called.
08-18 13:02:20.578 21561-21561/org.schabi.newpipe.debug D/MediaSourceManager@181009950: MediaSource - loadImmediate() called
    MediaSource - maybeClearLoaders() called.
    maybeLoadItem() called.
08-18 13:02:22.526 21561-21592/org.schabi.newpipe.debug D/EGL_emulation: eglMakeCurrent: 0x97fff9a0: ver 2 0 (tinfo 0xa62bff80)
08-18 13:02:22.548 21561-21592/org.schabi.newpipe.debug I/chatty: uid=10080(org.schabi.newpipe.debug) RenderThread identical 2 lines
08-18 13:02:22.575 21561-21592/org.schabi.newpipe.debug D/EGL_emulation: eglMakeCurrent: 0x97fff9a0: ver 2 0 (tinfo 0xa62bff80)
08-18 13:02:22.579 21561-21561/org.schabi.newpipe.debug D/MediaSourceManager@181009950: MediaSource - loadImmediate() called
    MediaSource - maybeClearLoaders() called.
    maybeLoadItem() called.

@karyogamy || @mauriciocolli could you please take a look at it. I will provide you with more information as I try to debug this.

@theScrabi theScrabi added the bug Issue is related to a bug label Aug 18, 2018
@karyogamy
Copy link
Contributor

I think this is again caused by the player trying to access a quality that is not available and the issue has been documented in #1328 and in the extractor. If I remember correctly, the extractor started providing unusable qualities since the 0.9 refactor, so maybe we can start looking there.

@theScrabi
Copy link
Member Author

Hm we could give it a try. However what i found out is when you try to pull out the url to the DASH MPD file, and feed it to VLC you will see that VLC player indeed uses a 480p resolution.

... I'll check this once more.

@karyogamy
Copy link
Contributor

What's stranger is the web browser player only goes up to 240p for the sample video.

Also, I think dash manifest is only available for older videos, so we probably can't reliably use it for parsing stream urls. Perhaps instead of parsing the manifest ourselves, maybe we can later implement a quality selector for live/dash/hls streams in the player and use dash instead of fmp4 for those videos providing manifests. You can experiment with it by removing this check.

@mauriciocolli
Copy link
Contributor

mauriciocolli commented Aug 18, 2018

What's stranger is the web browser player only goes up to 240p for the sample video.

It's a vertical video and I think YouTube returns the Itag's id based on format and the height, while in their UI, it takes the smallest side instead and round it to the nearest common resolution abbreviation.


The issue is that YouTube returns a segmented stream:

<Representation id="135" codecs="avc1.4d400b" width="270" height="480" startWithSAP="1"
                maxPlayoutRate="1" bandwidth="1155000" frameRate="30">
    <BaseURL>[...]googlevideo.com[...]/key/dg_yt0/</BaseURL>
    <SegmentList>
        <Initialization sourceURL="sq/0"/>
        <SegmentURL media="sq/1/dur/5.000"/>
        [...]
        <SegmentURL media="sq/12/dur/5.000"/>
        <SegmentURL media="sq/13/dur/2.700"/>
    </SegmentList>
</Representation>

While a player would parse it correctly, the extractor is blindly taking the BaseUrl and returning it as an accessible one, which is not true, as it's only used to build others.

However, if the segment list uses another delivery format (that uses range), the BaseUrl works fine (it points to the "whole" stream, without range):

<Representation id="134" codecs="avc1.4d400d" width="202" height="360" startWithSAP="1"
                maxPlayoutRate="1" bandwidth="324904" frameRate="30">
    <BaseURL>[...]googlevideo.com[...]/key/dg_yt0/</BaseURL>
    <SegmentList>
        <Initialization sourceURL="range/0-708"/>
        <SegmentURL media="range/897-183954"/>
        [...]
        <SegmentURL media="range/1761656-1913747"/>
        <SegmentURL media="range/1913748-2022062"/>
    </SegmentList>
</Representation>

The data source from the ExoPlayer receives a 404, but it just keeps retrying because of this. I'm not really familiar with the implementation anymore, so I don't really know why is set to the maximum.

But even though the retry is set to that value, it seems strange that a 404 is not assumed as a fatal error, maybe there's more implementation details to it?

@theScrabi
Copy link
Member Author

Hm so we need to change the way the back end is handling DASH files.

@karyogamy
Copy link
Contributor

The data source from the ExoPlayer receives a 404, but it just keeps retrying

Oh I see, nice find. setMinLoadableRetryCount(EXTRACTOR_MINIMUM_RETRY) is used internally by ExoPlayer to determine the max number of tries when starting the stream. I think retry was set to maximum to prevent Exoplayer from auto failing every stream in the play queue when there is a network failure on the device. So as a side effect, when a quality is unavailable, the player would be stuck to wait for user input.

But even though the retry is set to that value, it seems strange that a 404 is not assumed as a fatal error, maybe there's more implementation details to it?

I'm not sure what's causing the 404 on the sample video, the 480p stream fails on browser yet still plays on the web browser (with audio only), and it seems Exoplayer is actually able to sniff out the format of the stream and determine the source is mp4. ExoPlayer does throw a fatal error in case if it can't figure out the type of extractor needed to play the stream.

Hm so we need to change the way the back end is handling DASH files.

Why?

@theScrabi
Copy link
Member Author

Hm so we need to change the way the back end is handling DASH files.

Why?

Answer from @mauriciocolli

While a player would parse it correctly, the extractor is blindly taking the BaseUrl and returning it as an accessible one, which is not true, as it's only used to build others.

It does not make sense to return the BaseUrl if it can not be played without looking into the DASH MPD. I think it would make more sense if we didn't return a url here, but something that points to the corresponding element in the MPD file.

@theScrabi
Copy link
Member Author

theScrabi commented Aug 19, 2018

According to this blog entry you can either put the whole video into <BaseUrl>, or you can split it up using <SecmentationList>. So if the video is split into different segments this would be the case where we should not return <BaseUrl> as a "full working stream Url".

@theScrabi
Copy link
Member Author

The question now is, should we list such streams, or should we ignore them?

@karyogamy
Copy link
Contributor

I might be misunderstanding where we are going here, but isn't the problem that for most newer videos there is no dash manifest url available?

If a video does have a manifest, we can just modify the front end and use ExoPlayer to play the manifest directly instead of dealing it ourselves, as mentioned before. Why is parsing and cherry-picking the manifest preferable to just playing it here? Is there anything we can do for videos without manifest available?

@theScrabi
Copy link
Member Author

I might be misunderstanding where we are going here, but isn't the problem that for most newer videos there is no dash manifest url available?

Yes it seems that videos with a manifest are rather rare.

If a video does have a manifest, we can just modify the front end and use ExoPlayer to play the manifest directly instead of dealing it ourselves, as mentioned before.

The idea would be to get full working streams out of it as a fallback.

However the question I rose belonged to streams which where segmented, by means there is not one URL pointing to the stream, but many pointing to separate parts of it.

I've decided to ignore such streams, so they will not be shown in the selection. However @karyogamy just like you said, since ExoPlayer can handle such streams it could still play them, by directly parsing the MPD file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue is related to a bug
Projects
None yet
Development

No branches or pull requests

3 participants