{"id":1170,"date":"2021-09-13T12:53:58","date_gmt":"2021-09-13T10:53:58","guid":{"rendered":"https:\/\/websites.fraunhofer.de\/video-dev\/?p=1170"},"modified":"2021-09-13T12:53:59","modified_gmt":"2021-09-13T10:53:59","slug":"recovering-from-media_err_decode-errors-in-dash-js","status":"publish","type":"post","link":"https:\/\/websites.fraunhofer.de\/video-dev\/recovering-from-media_err_decode-errors-in-dash-js\/","title":{"rendered":"Recovering from MEDIA_ERR_DECODE errors in dash.js"},"content":{"rendered":"\n<p>One of the key features of a production grade video player is the ability to recover from critical errors. Talking about web-based video players there are a lot of potential errors that can cause the playback to fail. From our experience, one of the most common group of errors<strong> <\/strong>are the ones related to media decoding resulting in a <code>MEDIA_ERR_DECODE<\/code> thrown by the HTML5 video element. <\/p>\n\n\n\n<p>According to the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/MediaError\" target=\"_blank\" rel=\"noreferrer noopener\">MDN Web documentation<\/a> and the <a href=\"https:\/\/html.spec.whatwg.org\/multipage\/media.html#error-codes\" target=\"_blank\" rel=\"noreferrer noopener\">HTML specification <\/a> a <code>MEDIA_ERR_DECODE<\/code> occurs when the attempt to decode the media-data, previously been determined to be usable, results in an error,. <\/p>\n\n\n\n<p>With version 4.1.0 of <a href=\"https:\/\/github.com\/Dash-Industry-Forum\/dash.js\" target=\"_blank\" rel=\"noreferrer noopener\">dash.js <\/a> we are introducing a recover mechanism for such <code>MEDIA_ERR_DECODE <\/code>scenarios. By that, we account for potentially broken media-segments that can not be decoded..<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Catching decode errors<\/h2>\n\n\n\n<p>In order to handle errors we first register for all errors on the HTML5 video element:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>videoModel.addEventListener('error', _onPlaybackError)<\/code><\/pre>\n\n\n\n<p>Once a <code>MEDIA_ERR_DECODE<\/code> error occurs, we extract the error code and call the decode error handler <code>_handleMediaErrorDecode()<\/code>. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function _onPlaybackError(e) {\n        switch (e.error.code) {\n            case 3:\n                msg = 'MEDIA_ERR_DECODE';\n                _handleMediaErrorDecode();\n                break;\n}<\/code><\/pre>\n\n\n\n<p>A <code>MEDIA_ERR_DECODE<\/code> error is thrown right after the invalid media segment has been appended to the respective <code>SourceBuffer<\/code>. Consequently, the error is dispatched by the video element before we reach the problematic position in the buffer. For that reason,  we first save the current playback position. Next we reset some internal objects as well as the <code>MediaSource(MSE)<\/code>. As part of the the MSE reset we attach new <code>SourceBuffer<\/code> objects as well:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function _handleMediaErrorDecode() {\n    logger.warn('A MEDIA_ERR_DECODE occured: Resetting the MediaSource');\n\n    \/\/ Save the current playback position\n    const time = playbackController.getTime();\n    \n    \/\/ Deactivate the current stream.\n    activeStream.deactivate(false);\n\n    \/\/ Reset MSE\n    _openMediaSource(time, false);\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Blacklisting the problematic segment<\/h2>\n\n\n\n<p>In addition to resetting the <code>MediaSource<\/code> and the <code>SourceBuffer<\/code> objects we also need to blacklist the problematic segment. Otherwise the player will load the broken segment again and we end up with the same error. For that reason we register error handlers on the <code>SourceBuffer<\/code> objects. Once an error occurs during a <code>buffer.append<\/code> operation we get a notification and can forward the error to the class responsible for blacklisting the broken segments:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>buffer.addEventListener('error', _errHandler, false);\nfunction _errHandler(e) {\n    const error = e.target || {};\n    _triggerEvent(Events.SOURCE_BUFFER_ERROR, { error, lastRequestAppended })\n}<\/code><\/pre>\n\n\n\n<p>Note that we are blacklisting the segment url including the request range. The reason for that is that streams using a <code>SegmentBase<\/code> addressing scheme rely on the player issuing range requests on a single .mp4 file. If we simply blacklist the segment url the whole .mp4 would be blacklisted.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>eventBus.on(Events.SOURCE_BUFFER_ERROR, _onSourceBufferError, instance);\n\nfunction _onSourceBufferError(e) {\n    let blacklistUrl = e.lastRequestAppended.url;\n\n    if (e.lastRequestAppended.range) {\n        blacklistUrl = blacklistUrl.concat('_', e.lastRequestAppended.range);\n    }\n    logger.warn(`Blacklisting segment with url ${blacklistUrl}`);\n    segmentBlacklistController.add(blacklistUrl);\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Recovering from <code>MEDIA_ERR_DECODE<\/code> errors is one of many exciting new features in dash.js. It is already available in the <a href=\"https:\/\/reference.dashif.org\/dash.js\/nightly\/samples\/dash-if-reference-player\/index.html\" target=\"_blank\" rel=\"noreferrer noopener\">nightly build<\/a> of dash.js and will be part of the upcoming release (version 4.1.0). <\/p>\n\n\n\n<p>If you have any question regarding our DASH activities or dash.js in particular, feel free to check out our <a href=\"https:\/\/www.fokus.fraunhofer.de\/go\/dash\">website<\/a> and contact us.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the key features of a production grade video player is the ability to recover from critical errors. Talking about web-based video players there are a lot of potential errors that can cause the playback to fail. From our&#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,4,2],"tags":[],"coauthors":[6],"class_list":["post-1170","post","type-post","status-publish","format-standard","hentry","category-dash-js","category-media-source-extensions","category-mpeg-dash"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Recovering from MEDIA_ERR_DECODE errors in dash.js - Video-Dev<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/websites.fraunhofer.de\/video-dev\/recovering-from-media_err_decode-errors-in-dash-js\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Recovering from MEDIA_ERR_DECODE errors in dash.js - Video-Dev\" \/>\n<meta property=\"og:description\" content=\"One of the key features of a production grade video player is the ability to recover from critical errors. Talking about web-based video players there are a lot of potential errors that can cause the playback to fail. From our...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/websites.fraunhofer.de\/video-dev\/recovering-from-media_err_decode-errors-in-dash-js\/\" \/>\n<meta property=\"og:site_name\" content=\"Video-Dev\" \/>\n<meta property=\"article:published_time\" content=\"2021-09-13T10:53:58+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-09-13T10:53:59+00:00\" \/>\n<meta name=\"author\" content=\"Daniel Silhavy\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@dsilhavy\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Daniel Silhavy\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/recovering-from-media_err_decode-errors-in-dash-js\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/recovering-from-media_err_decode-errors-in-dash-js\\\/\"},\"author\":{\"name\":\"Daniel Silhavy\",\"@id\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/#\\\/schema\\\/person\\\/f7e1eee3cb4eae87a59648195014a809\"},\"headline\":\"Recovering from MEDIA_ERR_DECODE errors in dash.js\",\"datePublished\":\"2021-09-13T10:53:58+00:00\",\"dateModified\":\"2021-09-13T10:53:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/recovering-from-media_err_decode-errors-in-dash-js\\\/\"},\"wordCount\":409,\"commentCount\":0,\"articleSection\":[\"dash.js\",\"Media Source Extensions\",\"MPEG-DASH\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/recovering-from-media_err_decode-errors-in-dash-js\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/recovering-from-media_err_decode-errors-in-dash-js\\\/\",\"url\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/recovering-from-media_err_decode-errors-in-dash-js\\\/\",\"name\":\"Recovering from MEDIA_ERR_DECODE errors in dash.js - Video-Dev\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/#website\"},\"datePublished\":\"2021-09-13T10:53:58+00:00\",\"dateModified\":\"2021-09-13T10:53:59+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/#\\\/schema\\\/person\\\/f7e1eee3cb4eae87a59648195014a809\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/recovering-from-media_err_decode-errors-in-dash-js\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/recovering-from-media_err_decode-errors-in-dash-js\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/recovering-from-media_err_decode-errors-in-dash-js\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Recovering from MEDIA_ERR_DECODE errors in dash.js\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/#website\",\"url\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/\",\"name\":\"Video-Dev\",\"description\":\"Future Applications and Media - Video Development Blog\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/#\\\/schema\\\/person\\\/f7e1eee3cb4eae87a59648195014a809\",\"name\":\"Daniel Silhavy\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/0-1-150x150.jpegccb13c1b60303228bf3c575f3345fe29\",\"url\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/0-1-150x150.jpeg\",\"contentUrl\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/0-1-150x150.jpeg\",\"caption\":\"Daniel Silhavy\"},\"description\":\"Daniel Silhavy studied Computer Science at the Technical University of Berlin (TUB). He received his Masters degree with the completion of his thesis \u201cAd Insertion in MPEG-DASH\u201d at Fraunhofer Institute for Open Communication Systems (FOKUS) in 2015. Currently, he is employed as a scientific assistant and project manager at the Business Unit Future Applications and Media (FAME). He specializes in the R&amp;D of topics dealing with IPTV and adaptive media streaming.\",\"sameAs\":[\"https:\\\/\\\/www.fokus.fraunhofer.de\\\/fame\\\/team\\\/silhavy\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/daniel-silhavy-21650a129\\\/\",\"https:\\\/\\\/x.com\\\/dsilhavy\"],\"url\":\"https:\\\/\\\/websites.fraunhofer.de\\\/video-dev\\\/author\\\/silhavy\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Recovering from MEDIA_ERR_DECODE errors in dash.js - Video-Dev","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/websites.fraunhofer.de\/video-dev\/recovering-from-media_err_decode-errors-in-dash-js\/","og_locale":"en_US","og_type":"article","og_title":"Recovering from MEDIA_ERR_DECODE errors in dash.js - Video-Dev","og_description":"One of the key features of a production grade video player is the ability to recover from critical errors. Talking about web-based video players there are a lot of potential errors that can cause the playback to fail. From our...","og_url":"https:\/\/websites.fraunhofer.de\/video-dev\/recovering-from-media_err_decode-errors-in-dash-js\/","og_site_name":"Video-Dev","article_published_time":"2021-09-13T10:53:58+00:00","article_modified_time":"2021-09-13T10:53:59+00:00","author":"Daniel Silhavy","twitter_card":"summary_large_image","twitter_creator":"@dsilhavy","twitter_misc":{"Written by":"Daniel Silhavy","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/websites.fraunhofer.de\/video-dev\/recovering-from-media_err_decode-errors-in-dash-js\/#article","isPartOf":{"@id":"https:\/\/websites.fraunhofer.de\/video-dev\/recovering-from-media_err_decode-errors-in-dash-js\/"},"author":{"name":"Daniel Silhavy","@id":"https:\/\/websites.fraunhofer.de\/video-dev\/#\/schema\/person\/f7e1eee3cb4eae87a59648195014a809"},"headline":"Recovering from MEDIA_ERR_DECODE errors in dash.js","datePublished":"2021-09-13T10:53:58+00:00","dateModified":"2021-09-13T10:53:59+00:00","mainEntityOfPage":{"@id":"https:\/\/websites.fraunhofer.de\/video-dev\/recovering-from-media_err_decode-errors-in-dash-js\/"},"wordCount":409,"commentCount":0,"articleSection":["dash.js","Media Source Extensions","MPEG-DASH"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/websites.fraunhofer.de\/video-dev\/recovering-from-media_err_decode-errors-in-dash-js\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/websites.fraunhofer.de\/video-dev\/recovering-from-media_err_decode-errors-in-dash-js\/","url":"https:\/\/websites.fraunhofer.de\/video-dev\/recovering-from-media_err_decode-errors-in-dash-js\/","name":"Recovering from MEDIA_ERR_DECODE errors in dash.js - Video-Dev","isPartOf":{"@id":"https:\/\/websites.fraunhofer.de\/video-dev\/#website"},"datePublished":"2021-09-13T10:53:58+00:00","dateModified":"2021-09-13T10:53:59+00:00","author":{"@id":"https:\/\/websites.fraunhofer.de\/video-dev\/#\/schema\/person\/f7e1eee3cb4eae87a59648195014a809"},"breadcrumb":{"@id":"https:\/\/websites.fraunhofer.de\/video-dev\/recovering-from-media_err_decode-errors-in-dash-js\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/websites.fraunhofer.de\/video-dev\/recovering-from-media_err_decode-errors-in-dash-js\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/websites.fraunhofer.de\/video-dev\/recovering-from-media_err_decode-errors-in-dash-js\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/websites.fraunhofer.de\/video-dev\/"},{"@type":"ListItem","position":2,"name":"Recovering from MEDIA_ERR_DECODE errors in dash.js"}]},{"@type":"WebSite","@id":"https:\/\/websites.fraunhofer.de\/video-dev\/#website","url":"https:\/\/websites.fraunhofer.de\/video-dev\/","name":"Video-Dev","description":"Future Applications and Media - Video Development Blog","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/websites.fraunhofer.de\/video-dev\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/websites.fraunhofer.de\/video-dev\/#\/schema\/person\/f7e1eee3cb4eae87a59648195014a809","name":"Daniel Silhavy","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/websites.fraunhofer.de\/video-dev\/wp-content\/uploads\/2019\/11\/0-1-150x150.jpegccb13c1b60303228bf3c575f3345fe29","url":"https:\/\/websites.fraunhofer.de\/video-dev\/wp-content\/uploads\/2019\/11\/0-1-150x150.jpeg","contentUrl":"https:\/\/websites.fraunhofer.de\/video-dev\/wp-content\/uploads\/2019\/11\/0-1-150x150.jpeg","caption":"Daniel Silhavy"},"description":"Daniel Silhavy studied Computer Science at the Technical University of Berlin (TUB). He received his Masters degree with the completion of his thesis \u201cAd Insertion in MPEG-DASH\u201d at Fraunhofer Institute for Open Communication Systems (FOKUS) in 2015. Currently, he is employed as a scientific assistant and project manager at the Business Unit Future Applications and Media (FAME). He specializes in the R&amp;D of topics dealing with IPTV and adaptive media streaming.","sameAs":["https:\/\/www.fokus.fraunhofer.de\/fame\/team\/silhavy","https:\/\/www.linkedin.com\/in\/daniel-silhavy-21650a129\/","https:\/\/x.com\/dsilhavy"],"url":"https:\/\/websites.fraunhofer.de\/video-dev\/author\/silhavy\/"}]}},"_links":{"self":[{"href":"https:\/\/websites.fraunhofer.de\/video-dev\/wp-json\/wp\/v2\/posts\/1170","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/websites.fraunhofer.de\/video-dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/websites.fraunhofer.de\/video-dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/websites.fraunhofer.de\/video-dev\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/websites.fraunhofer.de\/video-dev\/wp-json\/wp\/v2\/comments?post=1170"}],"version-history":[{"count":17,"href":"https:\/\/websites.fraunhofer.de\/video-dev\/wp-json\/wp\/v2\/posts\/1170\/revisions"}],"predecessor-version":[{"id":1189,"href":"https:\/\/websites.fraunhofer.de\/video-dev\/wp-json\/wp\/v2\/posts\/1170\/revisions\/1189"}],"wp:attachment":[{"href":"https:\/\/websites.fraunhofer.de\/video-dev\/wp-json\/wp\/v2\/media?parent=1170"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/websites.fraunhofer.de\/video-dev\/wp-json\/wp\/v2\/categories?post=1170"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/websites.fraunhofer.de\/video-dev\/wp-json\/wp\/v2\/tags?post=1170"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/websites.fraunhofer.de\/video-dev\/wp-json\/wp\/v2\/coauthors?post=1170"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}