shaka-player
shaka-player copied to clipboard
Recover player after HTTP_ERROR
Have you read the Tutorials? yes
Have you read the FAQ and checked for duplicate open issues? yes
What version of Shaka Player are you using? 3.1.x
Please ask your question When the Shaka player cannot connect to the media server on fetching new data, even for a very short time, the player stops with error HTTP_ERROR 1002, with severity CRITICAL, which means the manifest needs to be reloaded. Error looks like this:
{
"severity": 2,
"category": 1,
"code": 1002,
"data": ["https://......mp4", {
"name": "TypeError",
"message": "NetworkError when attempting to fetch resource.",
"stack": ""
}
This is a very serious reaction to a common problem, which is a short break in internet connection.
I wonder if there is an easy way to recover the player after HTTP_ERROR? Can I configure Shaka player to react more friendly in this kind of situation and for example, wait for new content in "loading" state for N seconds and then try again? How do you deal with critical HTTP_ERROR?
OK, I think I found a proper combination of settings. I have significantly increased "maxAttempts" setting.
Could you please explain the difference between "timeout" and "connectionTimeout" settings? 20 seconds for timeout isn't too short? My current configuration:
player.configure({
drm: {
servers: supportedservers,
retryParameters: {
maxAttempts: 25
}
},
streaming: {
bufferingGoal: 25,
rebufferingGoal: 3,
bufferBehind: 10,
retryParameters: {
timeout: 20000,
stallTimeout: 6000,
connectionTimeout: 15000,
maxAttempts: 120,
baseDelay: 1000,
backoffFactor: 2,
fuzzFactor: 0.5,
}
},
abr: {
bandwidthDowngradeTarget: 0.95,
bandwidthUpgradeTarget: 0.85,
defaultBandwidthEstimate: 10000,
enabled: true,
switchInterval: 5
}
})
connectionTimeout
is for establishing the HTTP connection, not counting the request and response time.
timeout
is for entire transfer.
As for recovery, there is a streaming error callback you can use. See https://shaka-player-demo.appspot.com/docs/api/shaka.extern.html#.StreamingConfiguration and use streaming.failureCallback
.
A callback to decide what to do on a streaming failure. Default behavior is to retry on live streams and not on VOD.
But that description is a bit lacking. We should add more detail. If you want to continue streaming in spite of a streaming error, call player.retryStreaming()
. Here's what the default callback looks like in Player
:
https://github.com/google/shaka-player/blob/d5769eeda47524998a714a3d701604561d761b6d/lib/player.js#L4832-L4849
Does this help?
Great! Thank you, I missed this feature, it's very useful!
Glad this helped! I'm going to reopen the issue, tag it "docs", and convert it to a tracking bug to improve the documentation on this. Thanks!
Hi ! I downloaded and built the files today itself and ran into the same problem . I was checking out the code given in the Tutorials under the Basic Usage Section. Upon encountering the problem and viewing the above mentioned solution I tried to use player.retryStreaming()
in the following manner :
// Try to load a manifest.
// This is an asynchronous process.
try {
await player.load(manifestUri);
// This runs if the asynchronous load is successful.
console.log('The video has now been loaded!');
} catch (e) {
// onError is executed if the asynchronous load fails.
// shaka.log.warning('Live streaming error. Retrying automatically...');
console.log(player.retryStreaming());
onError(e);
}
And I still receive this error even though player.retryStreaming()
is returning true
I would be grateful if you could kindly suggest a solution to this problem . I would also love to update the documentation once this problem is solved.
Thank You
If load
fails, you need to call it again. retryStreaming
is only for errors that happen after playback has started. So this only makes sense in error
events.
player.addEventListener('error', () => {
// Error during playback, try to recover.
player.retryStreaming();
});
Oh ! Ok . Got it . Will try this out and then update the docs for the retryStreaming( )
function . Thank You for the help
Yup . Thank you for the suggestion @TheModMaker . This code works . It retrys loading the manifestUri
every 5 seconds . The player no longer needs to be reloaded after every failure .
const manifestUri =
'https://storage.googleapis.com/shaka-demo-assets/angel-one/dash.mpd';
function initApp() {
// Install built-in polyfills to patch browser incompatibilities.
shaka.polyfill.installAll();
// Check to see if the browser supports the basic APIs Shaka needs.
if (shaka.Player.isBrowserSupported()) {
// Everything looks good!
initPlayer();
} else {
// This browser does not have the minimum set of APIs we need.
console.error('Browser not supported!');
}
}
async function initPlayer() {
// Create a Player instance.
const video = document.getElementById('video');
const player = new shaka.Player(video);
// Attach player to the window to make it easy to access in the JS console.
window.player = player;
// Listen for error events.
player.addEventListener('error', onErrorEvent);
// Try to load a manifest.
// This is an asynchronous process.
try {
await player.load(manifestUri);
// This runs if the asynchronous load is successful.
console.log('The video has now been loaded!');
} catch (e) {
// onError is executed if the asynchronous load fails.
// shaka.log.warning('Live streaming error. Retrying automatically...');
onError(e);
}
}
function sleep(milliseconds) {
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
} while (currentDate - date < milliseconds);
}
function onErrorEvent(event) {
// Extract the shaka.util.Error object from the event.
onError(event.detail);
// in case of errors
player.retryStreaming();
}
async function onError(error) {
// in case of failure of the asynchronous load function
console.log("Load failed . Trying to reload manifestUri . . . in 3 seconds ");
sleep(5000);
if(error.code == 1002)
await player.load(manifestUri);
console.error('Error code', error.code, 'object', error.detail);
}
document.addEventListener('DOMContentLoaded', initApp);
Also do you think it would be a good idea to modify the documentation for the retryStreaming( )
function ? I think mentioning the difference between , when to use retryStreaming( )
and when to use the load( )
function could help future developers getting started more smoothly . Kindly provide your suggestions as to whether this should be done .
Thank You
Yes, we should improve the docs. This issue is being kept open to track docs improvements. Here are my suggestions:
- failureCallback should explain how it works (received error object, callback makes decision) and point to retryStreaming docs
- retryStreaming should explain when and how to use it (and when not to use it, such as when load() fails)
Yes . Agree with both the points . Especially the second one . I was trying to call retryStreaming( )
everytime load( )
was failing . I would like to make the necessary changes and contribute to the documentation . Will notify once the necessary changes have been made so that they can be reviewed and corrected if required . Really appreciate the suggestions .
Thank You
Hi there, I just set up the dev environment today and ran the tests. Everything worked completely fine until I tried to change the manifestUri in myapp.js in order to see how the errors are being handled. Looked for failureCallback in player_configuration.js and tried to understand how it works. I'm a newbie to open source and would like to contribute to improve the docs by making the two changes you suggested. @joeyparrish
Yes, we should improve the docs. This issue is being kept open to track docs improvements. Here are my suggestions:
- failureCallback should explain how it works (received error object, callback makes decision) and point to retryStreaming docs
- retryStreaming should explain when and how to use it (and when not to use it, such as when load() fails)
Fixed in https://github.com/shaka-project/shaka-player/pull/4983