shaka-project / shaka-player

JavaScript player library / DASH & HLS client / MSE-EME player
Apache License 2.0
7.06k stars 1.33k forks source link

Stuttering Dash DRM livestreaming video on WebOS 3.x #6321

Closed chornos13 closed 4 months ago

chornos13 commented 6 months ago

Have you read the FAQ and checked for duplicate open issues? Yes

What version of Shaka Player are you using?

v4.7.11 and v4.3.0

Can you reproduce the issue with our latest release version? yes in v4.7.11

Can you reproduce the issue with the latest code from main? not sure

Are you using the demo app or your own custom app? custom app

If custom app, can you reproduce the issue using our demo app? not sure

For embedded devices (smart TVs, etc.), what model and firmware version are you using? LG 2017 webOS TV Version 3.9.2-62912 (dreadlocks2-dudhwa) Model: 49UJ652T-TB

What are the manifest and license server URIs?

Firstly, we want to debug by ourselves. Maybe the Shaka team can share or give advice which parts of the Shaka codes we can check that are related to this issue because I can't share the manifest and license server URIs.

What configuration are you using? What is the output of player.getConfiguration()?

{
  "drm": {
    "retryParameters": {
      "maxAttempts": 2,
      "baseDelay": 1000,
      "backoffFactor": 2,
      "fuzzFactor": 0.5,
      "timeout": 30000,
      "stallTimeout": 5000,
      "connectionTimeout": 10000
    },
    "servers": {
      "com.widevine.alpha": "**censored**"
    },
    "clearKeys": {},
    "advanced": {},
    "delayLicenseRequestUntilPlayed": false,
    "persistentSessionOnlinePlayback": false,
    "persistentSessionsMetadata": [],
    "logLicenseExchange": false,
    "updateExpirationTime": 1,
    "preferredKeySystems": [],
    "keySystemsMapping": {},
    "parseInbandPsshEnabled": false,
    "minHdcpVersion": "",
    "ignoreDuplicateInitData": true
  },
  "manifest": {
    "retryParameters": {
      "maxAttempts": 2,
      "baseDelay": 1000,
      "backoffFactor": 2,
      "fuzzFactor": 0.5,
      "timeout": 30000,
      "stallTimeout": 5000,
      "connectionTimeout": 10000
    },
    "availabilityWindowOverride": 60,
    "disableAudio": false,
    "disableVideo": false,
    "disableText": false,
    "disableThumbnails": false,
    "defaultPresentationDelay": 0,
    "segmentRelativeVttTiming": false,
    "raiseFatalErrorOnManifestUpdateRequestFailure": false,
    "dash": {
      "clockSyncUri": "",
      "ignoreDrmInfo": false,
      "disableXlinkProcessing": false,
      "xlinkFailGracefully": false,
      "ignoreMinBufferTime": true,
      "autoCorrectDrift": true,
      "initialSegmentLimit": 1000,
      "ignoreSuggestedPresentationDelay": false,
      "ignoreEmptyAdaptationSet": false,
      "ignoreMaxSegmentDuration": false,
      "keySystemsByURI": {
        "urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b": "org.w3.clearkey",
        "urn:uuid:e2719d58-a985-b3c9-781a-b030af78d30e": "org.w3.clearkey",
        "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed": "com.widevine.alpha",
        "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95": "com.microsoft.playready",
        "urn:uuid:79f0049a-4098-8642-ab92-e65be0885f95": "com.microsoft.playready",
        "urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb": "com.adobe.primetime"
      },
      "sequenceMode": false,
      "enableAudioGroups": false,
      "multiTypeVariantsAllowed": false
    },
    "hls": {
      "ignoreTextStreamFailures": false,
      "ignoreImageStreamFailures": false,
      "defaultAudioCodec": "mp4a.40.2",
      "defaultVideoCodec": "avc1.42E01E",
      "ignoreManifestProgramDateTime": false,
      "mediaPlaylistFullMimeType": "video/mp2t; codecs=\"avc1.42E01E, mp4a.40.2\"",
      "useSafariBehaviorForLive": true,
      "liveSegmentsDelay": 3,
      "sequenceMode": false,
      "ignoreManifestTimestampsInSegmentsMode": false,
      "disableCodecGuessing": false,
      "allowLowLatencyByteRangeOptimization": true
    },
    "mss": {
      "sequenceMode": false,
      "keySystemsBySystemId": {
        "9a04f079-9840-4286-ab92-e65be0885f95": "com.microsoft.playready",
        "79f0049a-4098-8642-ab92-e65be0885f95": "com.microsoft.playready"
      }
    }
  },
  "streaming": {
    "retryParameters": {
      "maxAttempts": 2,
      "baseDelay": 1000,
      "backoffFactor": 2,
      "fuzzFactor": 0.5,
      "timeout": 30000,
      "stallTimeout": 5000,
      "connectionTimeout": 10000
    },
    "rebufferingGoal": 15,
    "bufferingGoal": 30,
    "bufferBehind": 15,
    "ignoreTextStreamFailures": false,
    "alwaysStreamText": false,
    "startAtSegmentBoundary": false,
    "gapDetectionThreshold": 0.5,
    "gapJumpTimerTime": 0.25,
    "durationBackoff": 1,
    "safeSeekOffset": 5,
    "stallEnabled": true,
    "stallThreshold": 10,
    "stallSkip": 0,
    "useNativeHlsOnSafari": true,
    "inaccurateManifestTolerance": 2,
    "lowLatencyMode": false,
    "autoLowLatencyMode": false,
    "forceHTTPS": false,
    "preferNativeHls": false,
    "updateIntervalSeconds": 1,
    "dispatchAllEmsgBoxes": false,
    "observeQualityChanges": false,
    "maxDisabledTime": 30,
    "parsePrftBox": false,
    "segmentPrefetchLimit": 0,
    "liveSync": false,
    "liveSyncMaxLatency": 1,
    "liveSyncPlaybackRate": 1.1,
    "liveSyncMinLatency": 0,
    "liveSyncMinPlaybackRate": 1,
    "allowMediaSourceRecoveries": true,
    "minTimeBetweenRecoveries": 5
  },
  "mediaSource": {
    "codecSwitchingStrategy": "reload",
    "sourceBufferExtraFeatures": "",
    "forceTransmux": false,
    "insertFakeEncryptionInInit": true
  },
  "offline": {
    "usePersistentLicense": true,
    "numberOfParallelDownloads": 5
  },
  "abr": {
    "enabled": true,
    "useNetworkInformation": true,
    "defaultBandwidthEstimate": 1000000,
    "switchInterval": 8,
    "bandwidthUpgradeTarget": 0.85,
    "bandwidthDowngradeTarget": 0.95,
    "restrictions": {
      "minWidth": 0,
      "maxWidth": 1280,
      "minHeight": 0,
      "maxHeight": 720,
      "minPixels": 0,
      "maxPixels": null,
      "minFrameRate": 0,
      "maxFrameRate": null,
      "minBandwidth": 0,
      "maxBandwidth": null
    },
    "advanced": {
      "minTotalBytes": 128000,
      "minBytes": 16000,
      "fastHalfLife": 2,
      "slowHalfLife": 5
    },
    "restrictToElementSize": false,
    "restrictToScreenSize": false,
    "ignoreDevicePixelRatio": false,
    "clearBufferSwitch": false,
    "safeMarginSwitch": 0
  },
  "autoShowText": 3,
  "preferredAudioLanguage": "",
  "preferredAudioLabel": "",
  "preferredTextLanguage": "",
  "preferredVariantRole": "",
  "preferredTextRole": "",
  "preferredAudioChannelCount": 2,
  "preferredVideoHdrLevel": "AUTO",
  "preferredVideoLayout": "",
  "preferredVideoLabel": "",
  "preferredVideoCodecs": [],
  "preferredAudioCodecs": [],
  "preferForcedSubs": false,
  "preferSpatialAudio": false,
  "preferredDecodingAttributes": [],
  "restrictions": {
    "minWidth": 0,
    "maxWidth": 1280,
    "minHeight": 0,
    "maxHeight": 720,
    "minPixels": 0,
    "maxPixels": null,
    "minFrameRate": 0,
    "maxFrameRate": null,
    "minBandwidth": 0,
    "maxBandwidth": null
  },
  "playRangeStart": 0,
  "playRangeEnd": null,
  "cmcd": {
    "enabled": false,
    "sessionId": "",
    "contentId": "",
    "useHeaders": false
  },
  "cmsd": {
    "enabled": true,
    "applyMaximumSuggestedBitrate": true,
    "estimatedThroughputWeightRatio": 0.5
  },
  "lcevc": {
    "enabled": false,
    "dynamicPerformanceScaling": true,
    "logLevel": 0,
    "drawLogo": false
  },
  "ads": {
    "customPlayheadTracker": false
  }
}

What did you do?

just playing the video Dash manifest, DRM Video codecs: avc1.64081f Audio codecs: mp4a.40.2 Segment format: m4s Live

What did you expect to happen? smooth playing

What actually happened?

only smooth playing for the first one second after buffering, after that it always stuttering.

https://github.com/shaka-project/shaka-player/assets/20974979/a8dd0b0e-b591-473e-9990-75cdfbb27dd1

koenoe commented 6 months ago

This is not meant as a solution, but we're having good results on older WebOS devices by disabling stall detection:

player.configure('streaming.stallEnabled', false);
joeyparrish commented 6 months ago

Firstly, we want to debug by ourselves. Maybe the Shaka team can share or give advice which parts of the Shaka codes we can check that are related to this issue because I can't share the manifest and license server URIs.

Definitely try configuration changes that might influence behavior, for example streaming.stallEnabled set to false as @koenoe suggested. That could help you find the right area of the code. If you find, for example, that stall detection is to blame, you could experiment with changes to the detection mechanisms and/or the logic executed on stall.

chornos13 commented 6 months ago

Firstly, we want to debug by ourselves. Maybe the Shaka team can share or give advice which parts of the Shaka codes we can check that are related to this issue because I can't share the manifest and license server URIs.

Definitely try configuration changes that might influence behavior, for example streaming.stallEnabled set to false as @koenoe suggested. That could help you find the right area of the code. If you find, for example, that stall detection is to blame, you could experiment with changes to the detection mechanisms and/or the logic executed on stall.

Hi @joeyparrish, sorry for the late reply. Yesterday, I tried setting streaming.stallEnabled to false, but the issue still persists. It seems to have no effect at all because I took a look at the logs, and there is no difference. I apologize for not providing clear information about the Shaka logs initially. Here are the attachments. I split them into two files because the app crashed when I enabled the log during the video initialization.

shaka-log-init.csv (video initialization) shaka-log-playing.csv (while playing where the stuttering happened)

I also tried this configuration and still no luck Note: The configurations below were not set all at once, I set them partially, flagged with a blank space.

  "drm": {
    "logLicenseExchange": true, 
    "delayLicenseRequestUntilPlayed": true,
    "ignoreDuplicateInitData": false
  },

  "manifest": {
    "disableAudio": true,
    "disableText": true,
    "disableThumbnails": true,

    "dash": {
      "sequenceMode": true,
    },

  "streaming": {
    // I noticed a difference when this configuration is applied, but it gets worse because now the video gets stuck around 60 seconds (not sure exactly), then starts stuttering again.
    "gapJumpTimerTime": 60,
    "updateIntervalSeconds": 60, 

    "stallEnabled": false,
  },
joeyparrish commented 6 months ago

Next you should try disabling gap jumping entirely. Maybe the seeks are causing a problem. Sometimes on these TV media pipelines, seeking is extremely expensive as it flushes a very long pipe of decoded frames.

Between not having access to your content and not having access to WebOS for testing, we (Shaka team at Google) can't do much more for you directly. Hopefully someone in the community with WebOS experience can offer you more advice.

steve-taylor commented 6 months ago

I'm seeing this on Shaka Player on webOS 4.x. We're actually doing a Shaka POC at the moment and one of the reasons is because we have this exact same issue, but with dash.js. It seems to be a lot worse on Shaka player, but we're yet do try tuning it with settings.

Do your live streams have SSAI, or is the manifest being refreshed frequently for any other reason? On dash.js, we found this to only be an issue with SSAI, which results in frequently updated large manifests, growing larger the longer the stream is live. (We allow users to play live or from the start.)

chornos13 commented 6 months ago

Hi @steve-taylor, currently, we don't have SSAI. We also don't have any other mechanism to refresh the manifest except by fetching the latest m4s using the built-in feature from Shaka. This issue also occurred even with lower quality (240p), so we still have no clue as to why this happened. However, we haven't asked the webOS community yet, as @joeyparrish suggested, but we will ask them soon.

Additional info: We also tried limiting the availabilityWindowOverride to 60 seconds, so users only have 60 seconds to seek, not from when the live stream started. However, the issue still persists.

avelad commented 5 months ago

Can someone test if this is still happening in the main branch? Thanks!

chornos13 commented 5 months ago

Can someone test if this is still happening in the main branch? Thanks!

image

I encountered this error, and I don't understand what is not supported because when I using v4.17.10 it worked fine. Here is the data I received when I visited https://shaka-player-demo.appspot.com/support.html.

Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 WebAppManager v4.7.11

{
  "manifest": {
    "application/dash+xml": true,
    "video/vnd.mpeg.dash.mpd": true,
    "application/x-mpegurl": true,
    "application/vnd.apple.mpegurl": true,
    "application/vnd.ms-sstr+xml": true,
    "application/x-offline-manifest": true
  },
  "media": {
    "video/mp4; codecs=\"avc1.42E01E\"": true,
    "video/mp4": true,
    "video/mp4; codecs=\"avc3.42E01E\"": true,
    "video/mp4; codecs=\"hev1.1.6.L93.90\"": true,
    "video/mp4; codecs=\"hvc1.1.6.L93.90\"": true,
    "video/mp4; codecs=\"hev1.2.4.L153.B0\"; eotf=\"smpte2084\"": true,
    "video/mp4; codecs=\"hvc1.2.4.L153.B0\"; eotf=\"smpte2084\"": true,
    "video/mp4; codecs=\"vp9\"": false,
    "video/mp4; codecs=\"vp09.00.10.08\"": false,
    "video/mp4; codecs=\"av01.0.01M.08\"": false,
    "video/mp4; codecs=\"dvh1.20.01\"": false,
    "audio/mp4; codecs=\"mp4a.40.2\"": true,
    "audio/mp4": true,
    "audio/mp4; codecs=\"ac-3\"": true,
    "audio/mp4; codecs=\"ec-3\"": true,
    "audio/mp4; codecs=\"ac-4\"": false,
    "audio/mp4; codecs=\"opus\"": false,
    "audio/mp4; codecs=\"flac\"": false,
    "audio/mp4; codecs=\"dtsc\"": false,
    "audio/mp4; codecs=\"dtse\"": false,
    "audio/mp4; codecs=\"dtsx\"": false,
    "video/webm; codecs=\"vp8\"": true,
    "video/webm": true,
    "video/webm; codecs=\"vp9\"": true,
    "video/webm; codecs=\"vp09.00.10.08\"": false,
    "audio/webm; codecs=\"vorbis\"": false,
    "audio/webm": false,
    "audio/webm; codecs=\"opus\"": false,
    "video/mp2t; codecs=\"avc1.42E01E\"": true,
    "video/mp2t": true,
    "video/mp2t; codecs=\"avc3.42E01E\"": true,
    "video/mp2t; codecs=\"hvc1.1.6.L93.90\"": true,
    "video/mp2t; codecs=\"mp4a.40.2\"": true,
    "video/mp2t; codecs=\"ac-3\"": true,
    "video/mp2t; codecs=\"ec-3\"": true,
    "text/vtt": true,
    "application/mp4; codecs=\"wvtt\"": true,
    "application/mp4": true,
    "application/ttml+xml": true,
    "application/mp4; codecs=\"stpp\"": true,
    "audio/aac": true,
    "audio/ac3": true,
    "audio/ec3": true,
    "audio/mpeg": true
  },
  "drm": {
    "com.microsoft.playready.recommendation": null,
    "com.apple.fps.1_0": null,
    "com.apple.fps": null,
    "com.adobe.primetime": null,
    "org.w3.clearkey": {
      "persistentState": false
    },
    "com.widevine.alpha": {
      "persistentState": false
    },
    "com.microsoft.playready": {
      "persistentState": false
    }
  },
  "offline": true
}
avelad commented 4 months ago

Can someone test if this is still happening in the main branch? Thanks! (we just fixed a bug that caused the main branch not to work on WebOS)

chornos13 commented 4 months ago

Hi @avelad, thank you for continuing to look into this issue. I have tested the main branch with version v4.7.11-main-65-ga6d27a915, but the problem is that it cannot play the video, it only requests the MPD and does not request the segment.

image

After that, I checked with the debug version to identify the problem. However, with the debug version, the video can play, but it still stutters.

By the way, we have investigated the issue further by experimenting with another player (videojs), but it still stutters. we also found that the stuttering disappears when we remove the DRM on the video with the same content and specification (codec).

So, based on our latest investigation, we believe the problem lies with the content rather than the player because of device capability.

For now, I will close the issue and reopen it if we find that the problem is indeed with the player. Thank you!