You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4910 lines
139 KiB

Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Fmp4 support (#829) * Media init segment support Resolve EXT-X-MAP URI information in the playlist loader. Add support for requesting and appending initialization segments to the segment loader. * Basic support for fragmented MP4 playback Re-arrange source updater and track support to fit our design goals more closely. Make adjustments so that the correct source buffer types are created when a fragmented mp4 is encountered. This version will play Apple's fMp4 bipbop stream but you have to seek the player to 10 seconds after starting because the first fragment starts at 10, not 0. * Finish consolidating audio loaders Manage a single pair of audio playlist and segment loaders, instead of one per track. Update track logic to work with the new flow. * Detect and set the correct starting timestamp offset Probe the init and first MP4 segment to correctly set timestamp offset so that the stream begins at time zero. After this change, Apple's fragmented MP4 HLS example stream plays without additional modification. * Guard against media playlists without bandwidth information If a media playlist is loaded directly or bandwidth info is unavailable, make sure the lowest bitrate check doesn't error. Add some unnecessary request shifting to tests to avoid extraneous requests caused by the current behavior of segment loader when abort()-ing THEN pause()-ing. * Add stub prog_index.m3u8 for tests Some of the tests point to master playlists that reference prog_index.m3u8. Sinon caught most of the exceptions related to this but the tests weren't really exercising realistic scenarios. Add a stub prog_index to the test fixtures so that requests for prog_index don't unintentionally error. * Abort init segment XHR alongside other segment XHRs If the segment loader XHRs are aborted, stop the init segment one as well. Make sure to check the right property for the init segment XHR before continuing the loading process. Make sure falsey values do not cause a playlist to be blacklisted in FF for audio info changes. * Fix audio track management after reorganization Delay segment loader initialization steps until all starting configuration is ready. This allowed source updater MIME types to be specified early without triggering the main updater to have its audio disabled on startup. Tweak the mime type identifier function to signal alternate audio earlier. Move `this` references in segment loader's checkBuffer_ out to stateful functions to align with the original design goals. Removed a segment loader test that seemed duplicative after the checkBuffer_ change. * Fix D3 on stats page Update URL for D3. Remove audio switcher since it's included by default now. * Only override codec defaults if an actual value was parsed When converting codec strings into MIME type configurations for source buffers, make sure to use default values if the codec string didn't supply particular fields. Export the codec to MIME helper function so it can be unit-tested. * IE fixes Array.prototype.find() isn't available in IE so use .filter()[0] instead. * Blacklist unsupported codecs If MediaSource.isTypeSupported fails in a generic MP4 container, swapping to a variant with those codecs is unlikely to be successful. For instance, the fragmented bip-bop stream includes AC-3 and EC-3 audio which is not supported on Chrome or Firefox today. Exclude variants with codecs that don't pass the isTypeSupported test.
9 years ago
Fmp4 support (#829) * Media init segment support Resolve EXT-X-MAP URI information in the playlist loader. Add support for requesting and appending initialization segments to the segment loader. * Basic support for fragmented MP4 playback Re-arrange source updater and track support to fit our design goals more closely. Make adjustments so that the correct source buffer types are created when a fragmented mp4 is encountered. This version will play Apple's fMp4 bipbop stream but you have to seek the player to 10 seconds after starting because the first fragment starts at 10, not 0. * Finish consolidating audio loaders Manage a single pair of audio playlist and segment loaders, instead of one per track. Update track logic to work with the new flow. * Detect and set the correct starting timestamp offset Probe the init and first MP4 segment to correctly set timestamp offset so that the stream begins at time zero. After this change, Apple's fragmented MP4 HLS example stream plays without additional modification. * Guard against media playlists without bandwidth information If a media playlist is loaded directly or bandwidth info is unavailable, make sure the lowest bitrate check doesn't error. Add some unnecessary request shifting to tests to avoid extraneous requests caused by the current behavior of segment loader when abort()-ing THEN pause()-ing. * Add stub prog_index.m3u8 for tests Some of the tests point to master playlists that reference prog_index.m3u8. Sinon caught most of the exceptions related to this but the tests weren't really exercising realistic scenarios. Add a stub prog_index to the test fixtures so that requests for prog_index don't unintentionally error. * Abort init segment XHR alongside other segment XHRs If the segment loader XHRs are aborted, stop the init segment one as well. Make sure to check the right property for the init segment XHR before continuing the loading process. Make sure falsey values do not cause a playlist to be blacklisted in FF for audio info changes. * Fix audio track management after reorganization Delay segment loader initialization steps until all starting configuration is ready. This allowed source updater MIME types to be specified early without triggering the main updater to have its audio disabled on startup. Tweak the mime type identifier function to signal alternate audio earlier. Move `this` references in segment loader's checkBuffer_ out to stateful functions to align with the original design goals. Removed a segment loader test that seemed duplicative after the checkBuffer_ change. * Fix D3 on stats page Update URL for D3. Remove audio switcher since it's included by default now. * Only override codec defaults if an actual value was parsed When converting codec strings into MIME type configurations for source buffers, make sure to use default values if the codec string didn't supply particular fields. Export the codec to MIME helper function so it can be unit-tested. * IE fixes Array.prototype.find() isn't available in IE so use .filter()[0] instead. * Blacklist unsupported codecs If MediaSource.isTypeSupported fails in a generic MP4 container, swapping to a variant with those codecs is unlikely to be successful. For instance, the fragmented bip-bop stream includes AC-3 and EC-3 audio which is not supported on Chrome or Firefox today. Exclude variants with codecs that don't pass the isTypeSupported test.
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Fmp4 support (#829) * Media init segment support Resolve EXT-X-MAP URI information in the playlist loader. Add support for requesting and appending initialization segments to the segment loader. * Basic support for fragmented MP4 playback Re-arrange source updater and track support to fit our design goals more closely. Make adjustments so that the correct source buffer types are created when a fragmented mp4 is encountered. This version will play Apple's fMp4 bipbop stream but you have to seek the player to 10 seconds after starting because the first fragment starts at 10, not 0. * Finish consolidating audio loaders Manage a single pair of audio playlist and segment loaders, instead of one per track. Update track logic to work with the new flow. * Detect and set the correct starting timestamp offset Probe the init and first MP4 segment to correctly set timestamp offset so that the stream begins at time zero. After this change, Apple's fragmented MP4 HLS example stream plays without additional modification. * Guard against media playlists without bandwidth information If a media playlist is loaded directly or bandwidth info is unavailable, make sure the lowest bitrate check doesn't error. Add some unnecessary request shifting to tests to avoid extraneous requests caused by the current behavior of segment loader when abort()-ing THEN pause()-ing. * Add stub prog_index.m3u8 for tests Some of the tests point to master playlists that reference prog_index.m3u8. Sinon caught most of the exceptions related to this but the tests weren't really exercising realistic scenarios. Add a stub prog_index to the test fixtures so that requests for prog_index don't unintentionally error. * Abort init segment XHR alongside other segment XHRs If the segment loader XHRs are aborted, stop the init segment one as well. Make sure to check the right property for the init segment XHR before continuing the loading process. Make sure falsey values do not cause a playlist to be blacklisted in FF for audio info changes. * Fix audio track management after reorganization Delay segment loader initialization steps until all starting configuration is ready. This allowed source updater MIME types to be specified early without triggering the main updater to have its audio disabled on startup. Tweak the mime type identifier function to signal alternate audio earlier. Move `this` references in segment loader's checkBuffer_ out to stateful functions to align with the original design goals. Removed a segment loader test that seemed duplicative after the checkBuffer_ change. * Fix D3 on stats page Update URL for D3. Remove audio switcher since it's included by default now. * Only override codec defaults if an actual value was parsed When converting codec strings into MIME type configurations for source buffers, make sure to use default values if the codec string didn't supply particular fields. Export the codec to MIME helper function so it can be unit-tested. * IE fixes Array.prototype.find() isn't available in IE so use .filter()[0] instead. * Blacklist unsupported codecs If MediaSource.isTypeSupported fails in a generic MP4 container, swapping to a variant with those codecs is unlikely to be successful. For instance, the fragmented bip-bop stream includes AC-3 and EC-3 audio which is not supported on Chrome or Firefox today. Exclude variants with codecs that don't pass the isTypeSupported test.
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Fmp4 support (#829) * Media init segment support Resolve EXT-X-MAP URI information in the playlist loader. Add support for requesting and appending initialization segments to the segment loader. * Basic support for fragmented MP4 playback Re-arrange source updater and track support to fit our design goals more closely. Make adjustments so that the correct source buffer types are created when a fragmented mp4 is encountered. This version will play Apple's fMp4 bipbop stream but you have to seek the player to 10 seconds after starting because the first fragment starts at 10, not 0. * Finish consolidating audio loaders Manage a single pair of audio playlist and segment loaders, instead of one per track. Update track logic to work with the new flow. * Detect and set the correct starting timestamp offset Probe the init and first MP4 segment to correctly set timestamp offset so that the stream begins at time zero. After this change, Apple's fragmented MP4 HLS example stream plays without additional modification. * Guard against media playlists without bandwidth information If a media playlist is loaded directly or bandwidth info is unavailable, make sure the lowest bitrate check doesn't error. Add some unnecessary request shifting to tests to avoid extraneous requests caused by the current behavior of segment loader when abort()-ing THEN pause()-ing. * Add stub prog_index.m3u8 for tests Some of the tests point to master playlists that reference prog_index.m3u8. Sinon caught most of the exceptions related to this but the tests weren't really exercising realistic scenarios. Add a stub prog_index to the test fixtures so that requests for prog_index don't unintentionally error. * Abort init segment XHR alongside other segment XHRs If the segment loader XHRs are aborted, stop the init segment one as well. Make sure to check the right property for the init segment XHR before continuing the loading process. Make sure falsey values do not cause a playlist to be blacklisted in FF for audio info changes. * Fix audio track management after reorganization Delay segment loader initialization steps until all starting configuration is ready. This allowed source updater MIME types to be specified early without triggering the main updater to have its audio disabled on startup. Tweak the mime type identifier function to signal alternate audio earlier. Move `this` references in segment loader's checkBuffer_ out to stateful functions to align with the original design goals. Removed a segment loader test that seemed duplicative after the checkBuffer_ change. * Fix D3 on stats page Update URL for D3. Remove audio switcher since it's included by default now. * Only override codec defaults if an actual value was parsed When converting codec strings into MIME type configurations for source buffers, make sure to use default values if the codec string didn't supply particular fields. Export the codec to MIME helper function so it can be unit-tested. * IE fixes Array.prototype.find() isn't available in IE so use .filter()[0] instead. * Blacklist unsupported codecs If MediaSource.isTypeSupported fails in a generic MP4 container, swapping to a variant with those codecs is unlikely to be successful. For instance, the fragmented bip-bop stream includes AC-3 and EC-3 audio which is not supported on Chrome or Firefox today. Exclude variants with codecs that don't pass the isTypeSupported test.
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Fmp4 support (#829) * Media init segment support Resolve EXT-X-MAP URI information in the playlist loader. Add support for requesting and appending initialization segments to the segment loader. * Basic support for fragmented MP4 playback Re-arrange source updater and track support to fit our design goals more closely. Make adjustments so that the correct source buffer types are created when a fragmented mp4 is encountered. This version will play Apple's fMp4 bipbop stream but you have to seek the player to 10 seconds after starting because the first fragment starts at 10, not 0. * Finish consolidating audio loaders Manage a single pair of audio playlist and segment loaders, instead of one per track. Update track logic to work with the new flow. * Detect and set the correct starting timestamp offset Probe the init and first MP4 segment to correctly set timestamp offset so that the stream begins at time zero. After this change, Apple's fragmented MP4 HLS example stream plays without additional modification. * Guard against media playlists without bandwidth information If a media playlist is loaded directly or bandwidth info is unavailable, make sure the lowest bitrate check doesn't error. Add some unnecessary request shifting to tests to avoid extraneous requests caused by the current behavior of segment loader when abort()-ing THEN pause()-ing. * Add stub prog_index.m3u8 for tests Some of the tests point to master playlists that reference prog_index.m3u8. Sinon caught most of the exceptions related to this but the tests weren't really exercising realistic scenarios. Add a stub prog_index to the test fixtures so that requests for prog_index don't unintentionally error. * Abort init segment XHR alongside other segment XHRs If the segment loader XHRs are aborted, stop the init segment one as well. Make sure to check the right property for the init segment XHR before continuing the loading process. Make sure falsey values do not cause a playlist to be blacklisted in FF for audio info changes. * Fix audio track management after reorganization Delay segment loader initialization steps until all starting configuration is ready. This allowed source updater MIME types to be specified early without triggering the main updater to have its audio disabled on startup. Tweak the mime type identifier function to signal alternate audio earlier. Move `this` references in segment loader's checkBuffer_ out to stateful functions to align with the original design goals. Removed a segment loader test that seemed duplicative after the checkBuffer_ change. * Fix D3 on stats page Update URL for D3. Remove audio switcher since it's included by default now. * Only override codec defaults if an actual value was parsed When converting codec strings into MIME type configurations for source buffers, make sure to use default values if the codec string didn't supply particular fields. Export the codec to MIME helper function so it can be unit-tested. * IE fixes Array.prototype.find() isn't available in IE so use .filter()[0] instead. * Blacklist unsupported codecs If MediaSource.isTypeSupported fails in a generic MP4 container, swapping to a variant with those codecs is unlikely to be successful. For instance, the fragmented bip-bop stream includes AC-3 and EC-3 audio which is not supported on Chrome or Firefox today. Exclude variants with codecs that don't pass the isTypeSupported test.
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Fmp4 support (#829) * Media init segment support Resolve EXT-X-MAP URI information in the playlist loader. Add support for requesting and appending initialization segments to the segment loader. * Basic support for fragmented MP4 playback Re-arrange source updater and track support to fit our design goals more closely. Make adjustments so that the correct source buffer types are created when a fragmented mp4 is encountered. This version will play Apple's fMp4 bipbop stream but you have to seek the player to 10 seconds after starting because the first fragment starts at 10, not 0. * Finish consolidating audio loaders Manage a single pair of audio playlist and segment loaders, instead of one per track. Update track logic to work with the new flow. * Detect and set the correct starting timestamp offset Probe the init and first MP4 segment to correctly set timestamp offset so that the stream begins at time zero. After this change, Apple's fragmented MP4 HLS example stream plays without additional modification. * Guard against media playlists without bandwidth information If a media playlist is loaded directly or bandwidth info is unavailable, make sure the lowest bitrate check doesn't error. Add some unnecessary request shifting to tests to avoid extraneous requests caused by the current behavior of segment loader when abort()-ing THEN pause()-ing. * Add stub prog_index.m3u8 for tests Some of the tests point to master playlists that reference prog_index.m3u8. Sinon caught most of the exceptions related to this but the tests weren't really exercising realistic scenarios. Add a stub prog_index to the test fixtures so that requests for prog_index don't unintentionally error. * Abort init segment XHR alongside other segment XHRs If the segment loader XHRs are aborted, stop the init segment one as well. Make sure to check the right property for the init segment XHR before continuing the loading process. Make sure falsey values do not cause a playlist to be blacklisted in FF for audio info changes. * Fix audio track management after reorganization Delay segment loader initialization steps until all starting configuration is ready. This allowed source updater MIME types to be specified early without triggering the main updater to have its audio disabled on startup. Tweak the mime type identifier function to signal alternate audio earlier. Move `this` references in segment loader's checkBuffer_ out to stateful functions to align with the original design goals. Removed a segment loader test that seemed duplicative after the checkBuffer_ change. * Fix D3 on stats page Update URL for D3. Remove audio switcher since it's included by default now. * Only override codec defaults if an actual value was parsed When converting codec strings into MIME type configurations for source buffers, make sure to use default values if the codec string didn't supply particular fields. Export the codec to MIME helper function so it can be unit-tested. * IE fixes Array.prototype.find() isn't available in IE so use .filter()[0] instead. * Blacklist unsupported codecs If MediaSource.isTypeSupported fails in a generic MP4 container, swapping to a variant with those codecs is unlikely to be successful. For instance, the fragmented bip-bop stream includes AC-3 and EC-3 audio which is not supported on Chrome or Firefox today. Exclude variants with codecs that don't pass the isTypeSupported test.
9 years ago
Fmp4 support (#829) * Media init segment support Resolve EXT-X-MAP URI information in the playlist loader. Add support for requesting and appending initialization segments to the segment loader. * Basic support for fragmented MP4 playback Re-arrange source updater and track support to fit our design goals more closely. Make adjustments so that the correct source buffer types are created when a fragmented mp4 is encountered. This version will play Apple's fMp4 bipbop stream but you have to seek the player to 10 seconds after starting because the first fragment starts at 10, not 0. * Finish consolidating audio loaders Manage a single pair of audio playlist and segment loaders, instead of one per track. Update track logic to work with the new flow. * Detect and set the correct starting timestamp offset Probe the init and first MP4 segment to correctly set timestamp offset so that the stream begins at time zero. After this change, Apple's fragmented MP4 HLS example stream plays without additional modification. * Guard against media playlists without bandwidth information If a media playlist is loaded directly or bandwidth info is unavailable, make sure the lowest bitrate check doesn't error. Add some unnecessary request shifting to tests to avoid extraneous requests caused by the current behavior of segment loader when abort()-ing THEN pause()-ing. * Add stub prog_index.m3u8 for tests Some of the tests point to master playlists that reference prog_index.m3u8. Sinon caught most of the exceptions related to this but the tests weren't really exercising realistic scenarios. Add a stub prog_index to the test fixtures so that requests for prog_index don't unintentionally error. * Abort init segment XHR alongside other segment XHRs If the segment loader XHRs are aborted, stop the init segment one as well. Make sure to check the right property for the init segment XHR before continuing the loading process. Make sure falsey values do not cause a playlist to be blacklisted in FF for audio info changes. * Fix audio track management after reorganization Delay segment loader initialization steps until all starting configuration is ready. This allowed source updater MIME types to be specified early without triggering the main updater to have its audio disabled on startup. Tweak the mime type identifier function to signal alternate audio earlier. Move `this` references in segment loader's checkBuffer_ out to stateful functions to align with the original design goals. Removed a segment loader test that seemed duplicative after the checkBuffer_ change. * Fix D3 on stats page Update URL for D3. Remove audio switcher since it's included by default now. * Only override codec defaults if an actual value was parsed When converting codec strings into MIME type configurations for source buffers, make sure to use default values if the codec string didn't supply particular fields. Export the codec to MIME helper function so it can be unit-tested. * IE fixes Array.prototype.find() isn't available in IE so use .filter()[0] instead. * Blacklist unsupported codecs If MediaSource.isTypeSupported fails in a generic MP4 container, swapping to a variant with those codecs is unlikely to be successful. For instance, the fragmented bip-bop stream includes AC-3 and EC-3 audio which is not supported on Chrome or Firefox today. Exclude variants with codecs that don't pass the isTypeSupported test.
9 years ago
Fmp4 support (#829) * Media init segment support Resolve EXT-X-MAP URI information in the playlist loader. Add support for requesting and appending initialization segments to the segment loader. * Basic support for fragmented MP4 playback Re-arrange source updater and track support to fit our design goals more closely. Make adjustments so that the correct source buffer types are created when a fragmented mp4 is encountered. This version will play Apple's fMp4 bipbop stream but you have to seek the player to 10 seconds after starting because the first fragment starts at 10, not 0. * Finish consolidating audio loaders Manage a single pair of audio playlist and segment loaders, instead of one per track. Update track logic to work with the new flow. * Detect and set the correct starting timestamp offset Probe the init and first MP4 segment to correctly set timestamp offset so that the stream begins at time zero. After this change, Apple's fragmented MP4 HLS example stream plays without additional modification. * Guard against media playlists without bandwidth information If a media playlist is loaded directly or bandwidth info is unavailable, make sure the lowest bitrate check doesn't error. Add some unnecessary request shifting to tests to avoid extraneous requests caused by the current behavior of segment loader when abort()-ing THEN pause()-ing. * Add stub prog_index.m3u8 for tests Some of the tests point to master playlists that reference prog_index.m3u8. Sinon caught most of the exceptions related to this but the tests weren't really exercising realistic scenarios. Add a stub prog_index to the test fixtures so that requests for prog_index don't unintentionally error. * Abort init segment XHR alongside other segment XHRs If the segment loader XHRs are aborted, stop the init segment one as well. Make sure to check the right property for the init segment XHR before continuing the loading process. Make sure falsey values do not cause a playlist to be blacklisted in FF for audio info changes. * Fix audio track management after reorganization Delay segment loader initialization steps until all starting configuration is ready. This allowed source updater MIME types to be specified early without triggering the main updater to have its audio disabled on startup. Tweak the mime type identifier function to signal alternate audio earlier. Move `this` references in segment loader's checkBuffer_ out to stateful functions to align with the original design goals. Removed a segment loader test that seemed duplicative after the checkBuffer_ change. * Fix D3 on stats page Update URL for D3. Remove audio switcher since it's included by default now. * Only override codec defaults if an actual value was parsed When converting codec strings into MIME type configurations for source buffers, make sure to use default values if the codec string didn't supply particular fields. Export the codec to MIME helper function so it can be unit-tested. * IE fixes Array.prototype.find() isn't available in IE so use .filter()[0] instead. * Blacklist unsupported codecs If MediaSource.isTypeSupported fails in a generic MP4 container, swapping to a variant with those codecs is unlikely to be successful. For instance, the fragmented bip-bop stream includes AC-3 and EC-3 audio which is not supported on Chrome or Firefox today. Exclude variants with codecs that don't pass the isTypeSupported test.
9 years ago
Fmp4 support (#829) * Media init segment support Resolve EXT-X-MAP URI information in the playlist loader. Add support for requesting and appending initialization segments to the segment loader. * Basic support for fragmented MP4 playback Re-arrange source updater and track support to fit our design goals more closely. Make adjustments so that the correct source buffer types are created when a fragmented mp4 is encountered. This version will play Apple's fMp4 bipbop stream but you have to seek the player to 10 seconds after starting because the first fragment starts at 10, not 0. * Finish consolidating audio loaders Manage a single pair of audio playlist and segment loaders, instead of one per track. Update track logic to work with the new flow. * Detect and set the correct starting timestamp offset Probe the init and first MP4 segment to correctly set timestamp offset so that the stream begins at time zero. After this change, Apple's fragmented MP4 HLS example stream plays without additional modification. * Guard against media playlists without bandwidth information If a media playlist is loaded directly or bandwidth info is unavailable, make sure the lowest bitrate check doesn't error. Add some unnecessary request shifting to tests to avoid extraneous requests caused by the current behavior of segment loader when abort()-ing THEN pause()-ing. * Add stub prog_index.m3u8 for tests Some of the tests point to master playlists that reference prog_index.m3u8. Sinon caught most of the exceptions related to this but the tests weren't really exercising realistic scenarios. Add a stub prog_index to the test fixtures so that requests for prog_index don't unintentionally error. * Abort init segment XHR alongside other segment XHRs If the segment loader XHRs are aborted, stop the init segment one as well. Make sure to check the right property for the init segment XHR before continuing the loading process. Make sure falsey values do not cause a playlist to be blacklisted in FF for audio info changes. * Fix audio track management after reorganization Delay segment loader initialization steps until all starting configuration is ready. This allowed source updater MIME types to be specified early without triggering the main updater to have its audio disabled on startup. Tweak the mime type identifier function to signal alternate audio earlier. Move `this` references in segment loader's checkBuffer_ out to stateful functions to align with the original design goals. Removed a segment loader test that seemed duplicative after the checkBuffer_ change. * Fix D3 on stats page Update URL for D3. Remove audio switcher since it's included by default now. * Only override codec defaults if an actual value was parsed When converting codec strings into MIME type configurations for source buffers, make sure to use default values if the codec string didn't supply particular fields. Export the codec to MIME helper function so it can be unit-tested. * IE fixes Array.prototype.find() isn't available in IE so use .filter()[0] instead. * Blacklist unsupported codecs If MediaSource.isTypeSupported fails in a generic MP4 container, swapping to a variant with those codecs is unlikely to be successful. For instance, the fragmented bip-bop stream includes AC-3 and EC-3 audio which is not supported on Chrome or Firefox today. Exclude variants with codecs that don't pass the isTypeSupported test.
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Fmp4 support (#829) * Media init segment support Resolve EXT-X-MAP URI information in the playlist loader. Add support for requesting and appending initialization segments to the segment loader. * Basic support for fragmented MP4 playback Re-arrange source updater and track support to fit our design goals more closely. Make adjustments so that the correct source buffer types are created when a fragmented mp4 is encountered. This version will play Apple's fMp4 bipbop stream but you have to seek the player to 10 seconds after starting because the first fragment starts at 10, not 0. * Finish consolidating audio loaders Manage a single pair of audio playlist and segment loaders, instead of one per track. Update track logic to work with the new flow. * Detect and set the correct starting timestamp offset Probe the init and first MP4 segment to correctly set timestamp offset so that the stream begins at time zero. After this change, Apple's fragmented MP4 HLS example stream plays without additional modification. * Guard against media playlists without bandwidth information If a media playlist is loaded directly or bandwidth info is unavailable, make sure the lowest bitrate check doesn't error. Add some unnecessary request shifting to tests to avoid extraneous requests caused by the current behavior of segment loader when abort()-ing THEN pause()-ing. * Add stub prog_index.m3u8 for tests Some of the tests point to master playlists that reference prog_index.m3u8. Sinon caught most of the exceptions related to this but the tests weren't really exercising realistic scenarios. Add a stub prog_index to the test fixtures so that requests for prog_index don't unintentionally error. * Abort init segment XHR alongside other segment XHRs If the segment loader XHRs are aborted, stop the init segment one as well. Make sure to check the right property for the init segment XHR before continuing the loading process. Make sure falsey values do not cause a playlist to be blacklisted in FF for audio info changes. * Fix audio track management after reorganization Delay segment loader initialization steps until all starting configuration is ready. This allowed source updater MIME types to be specified early without triggering the main updater to have its audio disabled on startup. Tweak the mime type identifier function to signal alternate audio earlier. Move `this` references in segment loader's checkBuffer_ out to stateful functions to align with the original design goals. Removed a segment loader test that seemed duplicative after the checkBuffer_ change. * Fix D3 on stats page Update URL for D3. Remove audio switcher since it's included by default now. * Only override codec defaults if an actual value was parsed When converting codec strings into MIME type configurations for source buffers, make sure to use default values if the codec string didn't supply particular fields. Export the codec to MIME helper function so it can be unit-tested. * IE fixes Array.prototype.find() isn't available in IE so use .filter()[0] instead. * Blacklist unsupported codecs If MediaSource.isTypeSupported fails in a generic MP4 container, swapping to a variant with those codecs is unlikely to be successful. For instance, the fragmented bip-bop stream includes AC-3 and EC-3 audio which is not supported on Chrome or Firefox today. Exclude variants with codecs that don't pass the isTypeSupported test.
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Fmp4 support (#829) * Media init segment support Resolve EXT-X-MAP URI information in the playlist loader. Add support for requesting and appending initialization segments to the segment loader. * Basic support for fragmented MP4 playback Re-arrange source updater and track support to fit our design goals more closely. Make adjustments so that the correct source buffer types are created when a fragmented mp4 is encountered. This version will play Apple's fMp4 bipbop stream but you have to seek the player to 10 seconds after starting because the first fragment starts at 10, not 0. * Finish consolidating audio loaders Manage a single pair of audio playlist and segment loaders, instead of one per track. Update track logic to work with the new flow. * Detect and set the correct starting timestamp offset Probe the init and first MP4 segment to correctly set timestamp offset so that the stream begins at time zero. After this change, Apple's fragmented MP4 HLS example stream plays without additional modification. * Guard against media playlists without bandwidth information If a media playlist is loaded directly or bandwidth info is unavailable, make sure the lowest bitrate check doesn't error. Add some unnecessary request shifting to tests to avoid extraneous requests caused by the current behavior of segment loader when abort()-ing THEN pause()-ing. * Add stub prog_index.m3u8 for tests Some of the tests point to master playlists that reference prog_index.m3u8. Sinon caught most of the exceptions related to this but the tests weren't really exercising realistic scenarios. Add a stub prog_index to the test fixtures so that requests for prog_index don't unintentionally error. * Abort init segment XHR alongside other segment XHRs If the segment loader XHRs are aborted, stop the init segment one as well. Make sure to check the right property for the init segment XHR before continuing the loading process. Make sure falsey values do not cause a playlist to be blacklisted in FF for audio info changes. * Fix audio track management after reorganization Delay segment loader initialization steps until all starting configuration is ready. This allowed source updater MIME types to be specified early without triggering the main updater to have its audio disabled on startup. Tweak the mime type identifier function to signal alternate audio earlier. Move `this` references in segment loader's checkBuffer_ out to stateful functions to align with the original design goals. Removed a segment loader test that seemed duplicative after the checkBuffer_ change. * Fix D3 on stats page Update URL for D3. Remove audio switcher since it's included by default now. * Only override codec defaults if an actual value was parsed When converting codec strings into MIME type configurations for source buffers, make sure to use default values if the codec string didn't supply particular fields. Export the codec to MIME helper function so it can be unit-tested. * IE fixes Array.prototype.find() isn't available in IE so use .filter()[0] instead. * Blacklist unsupported codecs If MediaSource.isTypeSupported fails in a generic MP4 container, swapping to a variant with those codecs is unlikely to be successful. For instance, the fragmented bip-bop stream includes AC-3 and EC-3 audio which is not supported on Chrome or Firefox today. Exclude variants with codecs that don't pass the isTypeSupported test.
9 years ago
Fmp4 support (#829) * Media init segment support Resolve EXT-X-MAP URI information in the playlist loader. Add support for requesting and appending initialization segments to the segment loader. * Basic support for fragmented MP4 playback Re-arrange source updater and track support to fit our design goals more closely. Make adjustments so that the correct source buffer types are created when a fragmented mp4 is encountered. This version will play Apple's fMp4 bipbop stream but you have to seek the player to 10 seconds after starting because the first fragment starts at 10, not 0. * Finish consolidating audio loaders Manage a single pair of audio playlist and segment loaders, instead of one per track. Update track logic to work with the new flow. * Detect and set the correct starting timestamp offset Probe the init and first MP4 segment to correctly set timestamp offset so that the stream begins at time zero. After this change, Apple's fragmented MP4 HLS example stream plays without additional modification. * Guard against media playlists without bandwidth information If a media playlist is loaded directly or bandwidth info is unavailable, make sure the lowest bitrate check doesn't error. Add some unnecessary request shifting to tests to avoid extraneous requests caused by the current behavior of segment loader when abort()-ing THEN pause()-ing. * Add stub prog_index.m3u8 for tests Some of the tests point to master playlists that reference prog_index.m3u8. Sinon caught most of the exceptions related to this but the tests weren't really exercising realistic scenarios. Add a stub prog_index to the test fixtures so that requests for prog_index don't unintentionally error. * Abort init segment XHR alongside other segment XHRs If the segment loader XHRs are aborted, stop the init segment one as well. Make sure to check the right property for the init segment XHR before continuing the loading process. Make sure falsey values do not cause a playlist to be blacklisted in FF for audio info changes. * Fix audio track management after reorganization Delay segment loader initialization steps until all starting configuration is ready. This allowed source updater MIME types to be specified early without triggering the main updater to have its audio disabled on startup. Tweak the mime type identifier function to signal alternate audio earlier. Move `this` references in segment loader's checkBuffer_ out to stateful functions to align with the original design goals. Removed a segment loader test that seemed duplicative after the checkBuffer_ change. * Fix D3 on stats page Update URL for D3. Remove audio switcher since it's included by default now. * Only override codec defaults if an actual value was parsed When converting codec strings into MIME type configurations for source buffers, make sure to use default values if the codec string didn't supply particular fields. Export the codec to MIME helper function so it can be unit-tested. * IE fixes Array.prototype.find() isn't available in IE so use .filter()[0] instead. * Blacklist unsupported codecs If MediaSource.isTypeSupported fails in a generic MP4 container, swapping to a variant with those codecs is unlikely to be successful. For instance, the fragmented bip-bop stream includes AC-3 and EC-3 audio which is not supported on Chrome or Firefox today. Exclude variants with codecs that don't pass the isTypeSupported test.
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
Simplified fetch algorithm as much as possible (#875) Fixed seeking behavior Updated getMediaIndexForTime to be simple and stupid Remove spurious console logs Fixed an issue with forward seeks and a different problem with backwards seeking (thanks Matt!). Fixed fast rendition change behavior. Remove limits on gap-skipper. Skip instantly without waiting. Use the proper native MediaSource duration for buffer removals. Improvements for live stream rendition changes Fixed an undefined variable bug Some more simplification and a very conservative live stream rendition change approach VOD fixes Experimental change to the way we throttle the fetcher Use GOAL_BUFFER_LENGTH again Continued massive changes to segment fetching. Cleanup and comments. Fixed a bug where we were fetching starting at mediaIndex 0 on every seek. Refactor probing code in preparation for pulling into it's own module or class Moved sync-related logic out of segment-loader and into a new sync-controller class Removed expired from the SegmentLoader Update mux.js dependency to 2.5.0 Don't error when the tsprobe returns null Fixed two issues: MAAT switching and Flash seeking Rename duration variable fix flash failing first segment load (#859) dont use tech for has played (#861) Code Coverage and Unit tests for Simple Fetcher (#862) fix has played returning false on vod (#866) Fixed preload="none" behavior and reduced the incidence of repeating initial segment requests (#878) Provide option to set contrib-hls first in the HTML5 tech (#889) This reverts commit 59ddbe1188c0b4a1d55d63fa7a334174001fbd28. Add playback tests (#894) Fixed MSE and environment test helpers, restore properly Removed unused test files remove expired time tracking and use sync points to calculate seekable (#898) Fixing a few tests for QUnit 2.0
9 years ago
  1. import document from 'global/document';
  2. import videojs from 'video.js';
  3. import Events from 'video.js';
  4. import QUnit from 'qunit';
  5. import testDataManifests from './dist/test-manifests.js';
  6. import {
  7. muxed as muxedSegment,
  8. encryptionKey,
  9. encrypted as encryptedSegment
  10. } from './dist/test-segments';
  11. import {
  12. useFakeEnvironment,
  13. useFakeMediaSource,
  14. createPlayer,
  15. openMediaSource,
  16. standardXHRResponse,
  17. absoluteUrl,
  18. requestAndAppendSegment,
  19. disposePlaybackWatcher
  20. } from './test-helpers.js';
  21. /* eslint-disable no-unused-vars */
  22. // we need this so that it can register hls with videojs
  23. import {
  24. HlsSourceHandler,
  25. HlsHandler,
  26. Hls,
  27. emeKeySystems,
  28. simpleTypeFromSourceType,
  29. LOCAL_STORAGE_KEY
  30. } from '../src/videojs-http-streaming';
  31. import window from 'global/window';
  32. // we need this so the plugin registers itself
  33. import 'videojs-contrib-quality-levels';
  34. import {version as vhsVersion} from '../package.json';
  35. import {version as muxVersion} from 'mux.js/package.json';
  36. import {version as mpdVersion} from 'mpd-parser/package.json';
  37. import {version as m3u8Version} from 'm3u8-parser/package.json';
  38. import {version as aesVersion} from 'aes-decrypter/package.json';
  39. let testOrSkip = 'test';
  40. // some tests just don't work reliably on ie11 or edge
  41. if (videojs.browser.IS_EDGE || videojs.browser.IE_VERSION) {
  42. testOrSkip = 'skip';
  43. }
  44. const ogHlsHandlerSetupQualityLevels = videojs.HlsHandler.prototype.setupQualityLevels_;
  45. // do a shallow copy of the properties of source onto the target object
  46. const merge = function(target, source) {
  47. let name;
  48. for (name in source) {
  49. target[name] = source[name];
  50. }
  51. };
  52. QUnit.module('HLS', {
  53. beforeEach(assert) {
  54. this.env = useFakeEnvironment(assert);
  55. this.requests = this.env.requests;
  56. this.mse = useFakeMediaSource();
  57. this.clock = this.env.clock;
  58. this.old = {};
  59. // store functionality that some tests need to mock
  60. this.old.GlobalOptions = videojs.mergeOptions(videojs.options);
  61. // force the HLS tech to run
  62. this.old.NativeHlsSupport = videojs.Hls.supportsNativeHls;
  63. videojs.Hls.supportsNativeHls = false;
  64. this.old.NativeDashSupport = videojs.Hls.supportsNativeDash;
  65. videojs.Hls.supportsNativeDash = false;
  66. this.old.Decrypt = videojs.Hls.Decrypter;
  67. videojs.Hls.Decrypter = function() {};
  68. // save and restore browser detection for the Firefox-specific tests
  69. this.old.browser = videojs.browser;
  70. videojs.browser = videojs.mergeOptions({}, videojs.browser);
  71. this.standardXHRResponse = (request, data) => {
  72. standardXHRResponse(request, data);
  73. // Because SegmentLoader#fillBuffer_ is now scheduled asynchronously
  74. // we have to use clock.tick to get the expected side effects of
  75. // SegmentLoader#handleAppendsDone_
  76. this.clock.tick(1);
  77. };
  78. // setup a player
  79. this.player = createPlayer();
  80. this.clock.tick(1);
  81. },
  82. afterEach() {
  83. this.env.restore();
  84. this.mse.restore();
  85. merge(videojs.options, this.old.GlobalOptions);
  86. videojs.Hls.supportsNativeHls = this.old.NativeHlsSupport;
  87. videojs.Hls.supportsNativeDash = this.old.NativeDashSupport;
  88. videojs.Hls.Decrypter = this.old.Decrypt;
  89. videojs.browser = this.old.browser;
  90. window.localStorage.clear();
  91. this.player.dispose();
  92. }
  93. });
  94. QUnit.test('version is exported', function(assert) {
  95. this.player.src({
  96. src: 'manifest/playlist.m3u8',
  97. type: 'application/vnd.apple.mpegurl'
  98. });
  99. this.clock.tick(1);
  100. assert.ok(this.player.vhs.version, 'version function');
  101. assert.ok(videojs.HlsHandler.version, 'version function');
  102. assert.deepEqual(this.player.vhs.version(), {
  103. '@videojs/http-streaming': vhsVersion,
  104. 'mux.js': muxVersion,
  105. 'mpd-parser': mpdVersion,
  106. 'm3u8-parser': m3u8Version,
  107. 'aes-decrypter': aesVersion
  108. }, 'version is correct');
  109. });
  110. QUnit.test('deprecation warning is show when using player.hls', function(assert) {
  111. const oldWarn = videojs.log.warn;
  112. let warning = '';
  113. let hlsPlayerAccessEvents = 0;
  114. this.player.src({
  115. src: 'manifest/playlist.m3u8',
  116. type: 'application/vnd.apple.mpegurl'
  117. });
  118. this.clock.tick(1);
  119. this.player.tech_.on('usage', (event) => {
  120. if (event.name === 'hls-player-access') {
  121. hlsPlayerAccessEvents++;
  122. }
  123. });
  124. videojs.log.warn = (text) => {
  125. warning = text;
  126. };
  127. assert.equal(hlsPlayerAccessEvents, 0, 'no hls-player-access event was fired');
  128. const hls = this.player.hls;
  129. assert.equal(hlsPlayerAccessEvents, 1, 'an hls-player-access event was fired');
  130. assert.equal(
  131. warning,
  132. 'player.hls is deprecated. Use player.tech().hls instead.',
  133. 'warning would have been shown'
  134. );
  135. assert.ok(hls, 'an instance of hls is returned by player.hls');
  136. videojs.log.warn = oldWarn;
  137. });
  138. QUnit.test('the HlsHandler instance is referenced by player.vhs', function(assert) {
  139. this.player.src({
  140. src: 'manifest/playlist.m3u8',
  141. type: 'application/vnd.apple.mpegurl'
  142. });
  143. this.clock.tick(1);
  144. assert.ok(
  145. this.player.vhs instanceof HlsHandler,
  146. 'player.vhs references an instance of HlsHandler'
  147. );
  148. });
  149. // deprecated, for backwards compatibility
  150. QUnit.test('the HlsHandler instance is referenced by player.dash', function(assert) {
  151. this.player.src({
  152. src: 'manifest/playlist.m3u8',
  153. type: 'application/vnd.apple.mpegurl'
  154. });
  155. this.clock.tick(1);
  156. assert.ok(
  157. this.player.dash instanceof HlsHandler,
  158. 'player.dash references an instance of HlsHandler'
  159. );
  160. });
  161. QUnit.test('starts playing if autoplay is specified', function(assert) {
  162. this.player.autoplay(true);
  163. this.player.src({
  164. src: 'manifest/playlist.m3u8',
  165. type: 'application/vnd.apple.mpegurl'
  166. });
  167. this.clock.tick(1);
  168. // make sure play() is called *after* the media source opens
  169. openMediaSource(this.player, this.clock);
  170. this.standardXHRResponse(this.requests[0]);
  171. assert.ok(!this.player.paused(), 'not paused');
  172. });
  173. QUnit.test('stats are reset on each new source', function(assert) {
  174. const done = assert.async();
  175. this.player.src({
  176. src: 'manifest/playlist.m3u8',
  177. type: 'application/vnd.apple.mpegurl'
  178. });
  179. this.clock.tick(1);
  180. // make sure play() is called *after* the media source opens
  181. openMediaSource(this.player, this.clock);
  182. const segment = muxedSegment();
  183. // copy the byte length since the segment bytes get cleared out
  184. const segmentByteLength = segment.byteLength;
  185. assert.ok(segmentByteLength, 'the segment has some number of bytes');
  186. // media
  187. this.standardXHRResponse(this.requests.shift());
  188. // segment 0
  189. this.standardXHRResponse(this.requests.shift(), segment);
  190. this.player.vhs.masterPlaylistController_.mainSegmentLoader_.one('appending', () => {
  191. assert.equal(
  192. this.player.tech_.hls.stats.mediaBytesTransferred,
  193. segmentByteLength,
  194. 'stat is set'
  195. );
  196. this.player.src({
  197. src: 'manifest/master.m3u8',
  198. type: 'application/vnd.apple.mpegurl'
  199. });
  200. this.clock.tick(1);
  201. assert.equal(this.player.tech_.hls.stats.mediaBytesTransferred, 0, 'stat is reset');
  202. done();
  203. });
  204. });
  205. QUnit.test('XHR requests first byte range on play', function(assert) {
  206. this.player.src({
  207. src: 'manifest/playlist.m3u8',
  208. type: 'application/vnd.apple.mpegurl'
  209. });
  210. this.clock.tick(1);
  211. this.player.tech_.triggerReady();
  212. this.clock.tick(1);
  213. this.player.tech_.trigger('play');
  214. openMediaSource(this.player, this.clock);
  215. this.standardXHRResponse(this.requests[0]);
  216. assert.equal(this.requests[1].headers.Range, 'bytes=0-522827');
  217. });
  218. QUnit.test('Seeking requests correct byte range', function(assert) {
  219. this.player.src({
  220. src: 'manifest/playlist.m3u8',
  221. type: 'application/vnd.apple.mpegurl'
  222. });
  223. this.clock.tick(1);
  224. this.player.tech_.trigger('play');
  225. openMediaSource(this.player, this.clock);
  226. this.standardXHRResponse(this.requests[0]);
  227. this.clock.tick(1);
  228. this.player.currentTime(41);
  229. this.clock.tick(2);
  230. assert.equal(this.requests[2].headers.Range, 'bytes=2299992-2835603');
  231. });
  232. QUnit.test('autoplay seeks to the live point after playlist load', function(assert) {
  233. let currentTime = 0;
  234. this.player.autoplay(true);
  235. this.player.tech_.currentTime = (ct) => {
  236. currentTime = ct;
  237. };
  238. this.player.src({
  239. src: 'liveStart30sBefore.m3u8',
  240. type: 'application/vnd.apple.mpegurl'
  241. });
  242. this.clock.tick(1);
  243. openMediaSource(this.player, this.clock);
  244. this.player.tech_.readyState = () => 4;
  245. this.player.tech_.trigger('play');
  246. this.standardXHRResponse(this.requests.shift());
  247. this.clock.tick(1);
  248. assert.notEqual(currentTime, 0, 'seeked on autoplay');
  249. });
  250. QUnit.test('autoplay seeks to the live point after media source open', function(assert) {
  251. let currentTime = 0;
  252. this.player.autoplay(true);
  253. this.player.tech_.setCurrentTime = (ct) => {
  254. currentTime = ct;
  255. };
  256. this.player.src({
  257. src: 'liveStart30sBefore.m3u8',
  258. type: 'application/vnd.apple.mpegurl'
  259. });
  260. this.player.tech_.readyState = () => 4;
  261. this.clock.tick(1);
  262. this.player.tech_.triggerReady();
  263. this.clock.tick(1);
  264. this.standardXHRResponse(this.requests.shift());
  265. openMediaSource(this.player, this.clock);
  266. this.player.tech_.trigger('play');
  267. this.clock.tick(1);
  268. assert.notEqual(currentTime, 0, 'seeked on autoplay');
  269. });
  270. QUnit.test(
  271. 'autoplay seeks to the live point after tech fires loadedmetadata in ie11',
  272. function(assert) {
  273. videojs.browser.IE_VERSION = 11;
  274. let currentTime = 0;
  275. this.player.autoplay(true);
  276. this.player.on('seeking', () => {
  277. currentTime = this.player.currentTime();
  278. });
  279. this.player.src({
  280. src: 'liveStart30sBefore.m3u8',
  281. type: 'application/vnd.apple.mpegurl'
  282. });
  283. this.clock.tick(1);
  284. openMediaSource(this.player, this.clock);
  285. this.player.tech_.trigger('play');
  286. this.standardXHRResponse(this.requests.shift());
  287. this.clock.tick(1);
  288. assert.equal(currentTime, 0, 'have not played yet');
  289. this.player.tech_.trigger('loadedmetadata');
  290. this.clock.tick(1);
  291. assert.notEqual(currentTime, 0, 'seeked after tech is ready');
  292. }
  293. );
  294. QUnit.test(
  295. 'duration is set when the source opens after the playlist is loaded',
  296. function(assert) {
  297. this.player.src({
  298. src: 'media.m3u8',
  299. type: 'application/vnd.apple.mpegurl'
  300. });
  301. this.clock.tick(1);
  302. this.player.tech_.triggerReady();
  303. this.clock.tick(1);
  304. this.standardXHRResponse(this.requests.shift());
  305. openMediaSource(this.player, this.clock);
  306. assert.equal(
  307. this.player.tech_.hls.mediaSource.duration,
  308. 40,
  309. 'set the duration'
  310. );
  311. }
  312. );
  313. QUnit.test('codecs are passed to the source buffer', function(assert) {
  314. const done = assert.async();
  315. const codecs = [];
  316. this.player.src({
  317. src: 'custom-codecs.m3u8',
  318. type: 'application/vnd.apple.mpegurl'
  319. });
  320. this.clock.tick(1);
  321. openMediaSource(this.player, this.clock);
  322. const addSourceBuffer = this.player.tech_.hls.mediaSource.addSourceBuffer;
  323. this.player.tech_.hls.mediaSource.addSourceBuffer = function(codec) {
  324. codecs.push(codec);
  325. return addSourceBuffer.call(this, codec);
  326. };
  327. // master
  328. this.requests.shift().respond(
  329. 200, null,
  330. '#EXTM3U\n' +
  331. '#EXT-X-STREAM-INF:CODECS="avc1.dd00dd, mp4a.40.9"\n' +
  332. 'media.m3u8\n'
  333. );
  334. // media
  335. this.standardXHRResponse(this.requests.shift());
  336. // segment 0
  337. this.standardXHRResponse(this.requests.shift(), muxedSegment());
  338. // source buffer won't be created until we have our first segment
  339. this.player.vhs.masterPlaylistController_.mainSegmentLoader_.one('appending', () => {
  340. // always create separate audio and video source buffers
  341. assert.equal(codecs.length, 2, 'created two source buffers');
  342. assert.equal(
  343. codecs[0],
  344. 'audio/mp4;codecs="mp4a.40.9"',
  345. 'specified the audio codec'
  346. );
  347. assert.equal(
  348. codecs[1],
  349. 'video/mp4;codecs="avc1.dd00dd"',
  350. 'specified the video codec'
  351. );
  352. done();
  353. });
  354. });
  355. QUnit.test('including HLS as a tech does not error', function(assert) {
  356. const player = createPlayer({
  357. techOrder: ['hls', 'html5']
  358. });
  359. this.clock.tick(1);
  360. assert.ok(player, 'created the player');
  361. assert.equal(this.env.log.warn.calls, 2, 'logged two warnings for deprecations');
  362. });
  363. QUnit.test('creates a PlaylistLoader on init', function(assert) {
  364. this.player.src({
  365. src: 'manifest/playlist.m3u8',
  366. type: 'application/vnd.apple.mpegurl'
  367. });
  368. this.clock.tick(1);
  369. openMediaSource(this.player, this.clock);
  370. this.player.src({
  371. src: 'manifest/playlist.m3u8',
  372. type: 'application/vnd.apple.mpegurl'
  373. });
  374. this.clock.tick(1);
  375. openMediaSource(this.player, this.clock);
  376. assert.equal(this.requests[0].aborted, true, 'aborted previous src');
  377. this.standardXHRResponse(this.requests[1]);
  378. assert.ok(
  379. this.player.tech_.hls.playlists.master,
  380. 'set the master playlist'
  381. );
  382. assert.ok(
  383. this.player.tech_.hls.playlists.media(),
  384. 'set the media playlist'
  385. );
  386. assert.ok(
  387. this.player.tech_.hls.playlists.media().segments,
  388. 'the segment entries are parsed'
  389. );
  390. assert.strictEqual(
  391. this.player.tech_.hls.playlists.master.playlists[0],
  392. this.player.tech_.hls.playlists.media(),
  393. 'the playlist is selected'
  394. );
  395. });
  396. QUnit.test('sets the duration if one is available on the playlist', function(assert) {
  397. let events = 0;
  398. this.player.src({
  399. src: 'manifest/media.m3u8',
  400. type: 'application/vnd.apple.mpegurl'
  401. });
  402. this.clock.tick(1);
  403. openMediaSource(this.player, this.clock);
  404. this.player.tech_.on('durationchange', function() {
  405. events++;
  406. });
  407. this.standardXHRResponse(this.requests[0]);
  408. assert.equal(
  409. this.player.tech_.hls.mediaSource.duration,
  410. 40,
  411. 'set the duration'
  412. );
  413. assert.equal(events, 1, 'durationchange is fired');
  414. });
  415. QUnit.test('estimates individual segment durations if needed', function(assert) {
  416. let changes = 0;
  417. this.player.src({
  418. src: 'http://example.com/manifest/missingExtinf.m3u8',
  419. type: 'application/vnd.apple.mpegurl'
  420. });
  421. this.clock.tick(1);
  422. openMediaSource(this.player, this.clock);
  423. this.player.tech_.hls.mediaSource.duration = NaN;
  424. this.player.tech_.on('durationchange', function() {
  425. changes++;
  426. });
  427. this.standardXHRResponse(this.requests[0]);
  428. assert.strictEqual(
  429. this.player.tech_.hls.mediaSource.duration,
  430. this.player.tech_.hls.playlists.media().segments.length * 10,
  431. 'duration is updated'
  432. );
  433. assert.strictEqual(changes, 1, 'one durationchange fired');
  434. });
  435. QUnit.test(
  436. 'translates seekable by the starting time for live playlists',
  437. function(assert) {
  438. this.player.src({
  439. src: 'media.m3u8',
  440. type: 'application/vnd.apple.mpegurl'
  441. });
  442. this.clock.tick(1);
  443. openMediaSource(this.player, this.clock);
  444. this.requests.shift().respond(
  445. 200, null,
  446. '#EXTM3U\n' +
  447. '#EXT-X-MEDIA-SEQUENCE:15\n' +
  448. '#EXT-X-TARGETDURATION:10\n' +
  449. '#EXTINF:10,\n' +
  450. '0.ts\n' +
  451. '#EXTINF:10,\n' +
  452. '1.ts\n' +
  453. '#EXTINF:10,\n' +
  454. '2.ts\n' +
  455. '#EXTINF:10,\n' +
  456. '3.ts\n'
  457. );
  458. const seekable = this.player.seekable();
  459. assert.equal(seekable.length, 1, 'one seekable range');
  460. assert.equal(seekable.start(0), 0, 'the earliest possible position is at zero');
  461. assert.equal(seekable.end(0), 10, 'end is relative to the start');
  462. }
  463. );
  464. QUnit.test('starts downloading a segment on loadedmetadata', function(assert) {
  465. const done = assert.async();
  466. this.player.src({
  467. src: 'manifest/media.m3u8',
  468. type: 'application/vnd.apple.mpegurl'
  469. });
  470. this.clock.tick(1);
  471. this.player.buffered = function() {
  472. return videojs.createTimeRange(0, 0);
  473. };
  474. openMediaSource(this.player, this.clock);
  475. const segment = muxedSegment();
  476. // copy the byte length since the segment bytes get cleared out
  477. const segmentByteLength = segment.byteLength;
  478. assert.ok(segmentByteLength, 'the segment has some number of bytes');
  479. // media
  480. this.standardXHRResponse(this.requests[0]);
  481. // segment 0
  482. this.standardXHRResponse(this.requests[1], segment);
  483. assert.strictEqual(
  484. this.requests[1].url,
  485. absoluteUrl('manifest/media-00001.ts'),
  486. 'the first segment is requested'
  487. );
  488. this.player.vhs.masterPlaylistController_.mainSegmentLoader_.one('appending', () => {
  489. // verify stats
  490. assert.equal(
  491. this.player.tech_.hls.stats.mediaBytesTransferred,
  492. segmentByteLength,
  493. 'transferred the segment byte length'
  494. );
  495. assert.equal(this.player.tech_.hls.stats.mediaRequests, 1, '1 request');
  496. done();
  497. });
  498. });
  499. QUnit.test('re-initializes the handler for each source', function(assert) {
  500. let secondPlaylists;
  501. let secondMSE;
  502. this.player.src({
  503. src: 'manifest/master.m3u8',
  504. type: 'application/vnd.apple.mpegurl'
  505. });
  506. this.clock.tick(1);
  507. openMediaSource(this.player, this.clock);
  508. const firstPlaylists = this.player.tech_.hls.playlists;
  509. const firstMSE = this.player.tech_.hls.mediaSource;
  510. // master
  511. this.standardXHRResponse(this.requests.shift());
  512. // media
  513. this.standardXHRResponse(this.requests.shift());
  514. const mpc = this.player.tech_.hls.masterPlaylistController_;
  515. // need a segment request to complete for the source buffers to be created
  516. return requestAndAppendSegment({
  517. request: this.requests.shift(),
  518. mediaSource: mpc.mediaSource,
  519. segmentLoader: mpc.mainSegmentLoader_,
  520. clock: this.clock,
  521. tickClock: false
  522. }).then(() => {
  523. let audioBufferAborts = 0;
  524. let videoBufferAborts = 0;
  525. mpc.mainSegmentLoader_.sourceUpdater_.audioBuffer.abort = () => audioBufferAborts++;
  526. mpc.mainSegmentLoader_.sourceUpdater_.videoBuffer.abort = () => videoBufferAborts++;
  527. // allow timeout for making another request
  528. this.clock.tick(1);
  529. assert.equal(this.requests.length, 1, 'made another request');
  530. this.player.src({
  531. src: 'manifest/master.m3u8',
  532. type: 'application/vnd.apple.mpegurl'
  533. });
  534. this.clock.tick(1);
  535. openMediaSource(this.player, this.clock);
  536. secondPlaylists = this.player.tech_.hls.playlists;
  537. secondMSE = this.player.tech_.hls.mediaSource;
  538. assert.equal(audioBufferAborts, 1, 'aborted the old audio source buffer');
  539. assert.equal(videoBufferAborts, 1, 'aborted the old video source buffer');
  540. assert.ok(this.requests[0].aborted, 'aborted the old segment request');
  541. assert.notStrictEqual(
  542. firstPlaylists,
  543. secondPlaylists,
  544. 'the playlist object is not reused'
  545. );
  546. assert.notStrictEqual(firstMSE, secondMSE, 'the media source object is not reused');
  547. });
  548. });
  549. QUnit.test(
  550. 'triggers a media source error when an initial playlist request errors',
  551. function(assert) {
  552. this.player.src({
  553. src: 'manifest/master.m3u8',
  554. type: 'application/vnd.apple.mpegurl'
  555. });
  556. this.clock.tick(1);
  557. openMediaSource(this.player, this.clock);
  558. this.requests.pop().respond(500);
  559. assert.equal(
  560. this.player.tech_.hls.mediaSource.error_,
  561. 'network',
  562. 'a network error is triggered'
  563. );
  564. }
  565. );
  566. QUnit.test(
  567. 'triggers a player error when an initial playlist request errors and the media source ' +
  568. 'isn\'t open',
  569. function(assert) {
  570. const done = assert.async();
  571. const origError = videojs.log.error;
  572. const errLogs = [];
  573. const endOfStreams = [];
  574. videojs.log.error = (log) => errLogs.push(log);
  575. this.player.src({
  576. src: 'manifest/master.m3u8',
  577. type: 'application/vnd.apple.mpegurl'
  578. });
  579. openMediaSource(this.player, this.clock);
  580. this.player.tech_.hls.masterPlaylistController_.mediaSource.readyState = 'closed';
  581. this.player.on('error', () => {
  582. const error = this.player.error();
  583. assert.equal(error.code, 2, 'error has correct code');
  584. assert.equal(
  585. error.message,
  586. 'HLS playlist request error at URL: manifest/master.m3u8.',
  587. 'error has correct message'
  588. );
  589. assert.equal(errLogs.length, 1, 'logged an error');
  590. videojs.log.error = origError;
  591. assert.notOk(this.player.tech_.hls.mediaSource.error_, 'no media source error');
  592. done();
  593. });
  594. this.requests.pop().respond(500);
  595. }
  596. );
  597. QUnit.test('downloads media playlists after loading the master', function(assert) {
  598. const done = assert.async();
  599. this.player.src({
  600. src: 'manifest/master.m3u8',
  601. type: 'application/vnd.apple.mpegurl'
  602. });
  603. this.clock.tick(1);
  604. openMediaSource(this.player, this.clock);
  605. this.player.tech_.hls.bandwidth = 20e10;
  606. // master
  607. this.standardXHRResponse(this.requests[0]);
  608. // media
  609. this.standardXHRResponse(this.requests[1]);
  610. const segment = muxedSegment();
  611. // copy the byte length since the segment bytes get cleared out
  612. const segmentByteLength = segment.byteLength;
  613. assert.ok(segmentByteLength, 'the segment has some number of bytes');
  614. // segment 0
  615. this.standardXHRResponse(this.requests[2], segment);
  616. assert.strictEqual(
  617. this.requests[0].url,
  618. 'manifest/master.m3u8',
  619. 'master playlist requested'
  620. );
  621. assert.strictEqual(
  622. this.requests[1].url,
  623. absoluteUrl('manifest/media2.m3u8'),
  624. 'media playlist requested'
  625. );
  626. assert.strictEqual(
  627. this.requests[2].url,
  628. absoluteUrl('manifest/media2-00001.ts'),
  629. 'first segment requested'
  630. );
  631. this.player.vhs.masterPlaylistController_.mainSegmentLoader_.one('appending', () => {
  632. // verify stats
  633. assert.equal(
  634. this.player.tech_.hls.stats.mediaBytesTransferred,
  635. segmentByteLength,
  636. 'transferred the segment byte length'
  637. );
  638. assert.equal(this.player.tech_.hls.stats.mediaRequests, 1, '1 request');
  639. done();
  640. });
  641. });
  642. QUnit.test('setting bandwidth resets throughput', function(assert) {
  643. this.player.src({
  644. src: 'manifest/master.m3u8',
  645. type: 'application/vnd.apple.mpegurl'
  646. });
  647. this.clock.tick(1);
  648. this.player.tech_.hls.throughput = 1000;
  649. assert.strictEqual(
  650. this.player.tech_.hls.throughput,
  651. 1000,
  652. 'throughput is set'
  653. );
  654. this.player.tech_.hls.bandwidth = 20e10;
  655. assert.strictEqual(
  656. this.player.tech_.hls.throughput,
  657. 0,
  658. 'throughput is reset when bandwidth is specified'
  659. );
  660. });
  661. QUnit.test('a thoughput of zero is ignored in systemBandwidth', function(assert) {
  662. this.player.src({
  663. src: 'manifest/master.m3u8',
  664. type: 'application/vnd.apple.mpegurl'
  665. });
  666. this.clock.tick(1);
  667. this.player.tech_.hls.bandwidth = 20e10;
  668. assert.strictEqual(
  669. this.player.tech_.hls.throughput,
  670. 0,
  671. 'throughput is reset when bandwidth is specified'
  672. );
  673. assert.strictEqual(
  674. this.player.tech_.hls.systemBandwidth,
  675. 20e10,
  676. 'systemBandwidth is the same as bandwidth'
  677. );
  678. });
  679. QUnit.test(
  680. 'systemBandwidth is a combination of thoughput and bandwidth',
  681. function(assert) {
  682. this.player.src({
  683. src: 'manifest/master.m3u8',
  684. type: 'application/vnd.apple.mpegurl'
  685. });
  686. this.clock.tick(1);
  687. this.player.tech_.hls.bandwidth = 20e10;
  688. this.player.tech_.hls.throughput = 20e10;
  689. // 1 / ( 1 / 20e10 + 1 / 20e10) = 10e10
  690. assert.strictEqual(
  691. this.player.tech_.hls.systemBandwidth,
  692. 10e10,
  693. 'systemBandwidth is the combination of bandwidth and throughput'
  694. );
  695. }
  696. );
  697. QUnit.test('requests a reasonable rendition to start', function(assert) {
  698. this.player.src({
  699. src: 'manifest/master.m3u8',
  700. type: 'application/vnd.apple.mpegurl'
  701. });
  702. this.clock.tick(1);
  703. openMediaSource(this.player, this.clock);
  704. this.standardXHRResponse(
  705. this.requests[0],
  706. '#EXTM3U\n' +
  707. '#EXT-X-STREAM-INF:BANDWIDTH=50\n' +
  708. 'mediaLow.m3u8\n' +
  709. '#EXT-X-STREAM-INF:BANDWIDTH=240000\n' +
  710. 'mediaNormal.m3u8\n' +
  711. '#EXT-X-STREAM-INF:BANDWIDTH=19280000000\n' +
  712. 'mediaHigh.m3u8\n'
  713. );
  714. assert.strictEqual(
  715. this.requests[0].url,
  716. 'manifest/master.m3u8',
  717. 'master playlist requested'
  718. );
  719. assert.strictEqual(
  720. this.requests[1].url,
  721. absoluteUrl('manifest/mediaNormal.m3u8'),
  722. 'reasonable bandwidth media playlist requested'
  723. );
  724. });
  725. QUnit.test('upshifts if the initial bandwidth hint is high', function(assert) {
  726. this.player.src({
  727. src: 'manifest/master.m3u8',
  728. type: 'application/vnd.apple.mpegurl'
  729. });
  730. this.clock.tick(1);
  731. openMediaSource(this.player, this.clock);
  732. this.player.tech_.hls.bandwidth = 10e20;
  733. this.standardXHRResponse(
  734. this.requests[0],
  735. '#EXTM3U\n' +
  736. '#EXT-X-STREAM-INF:BANDWIDTH=50\n' +
  737. 'mediaLow.m3u8\n' +
  738. '#EXT-X-STREAM-INF:BANDWIDTH=240000\n' +
  739. 'mediaNormal.m3u8\n' +
  740. '#EXT-X-STREAM-INF:BANDWIDTH=19280000000\n' +
  741. 'mediaHigh.m3u8\n'
  742. );
  743. assert.strictEqual(
  744. this.requests[0].url,
  745. 'manifest/master.m3u8',
  746. 'master playlist requested'
  747. );
  748. assert.strictEqual(
  749. this.requests[1].url,
  750. absoluteUrl('manifest/mediaHigh.m3u8'),
  751. 'high bandwidth media playlist requested'
  752. );
  753. });
  754. QUnit.test('downshifts if the initial bandwidth hint is low', function(assert) {
  755. this.player.src({
  756. src: 'manifest/master.m3u8',
  757. type: 'application/vnd.apple.mpegurl'
  758. });
  759. this.clock.tick(1);
  760. openMediaSource(this.player, this.clock);
  761. this.player.tech_.hls.bandwidth = 100;
  762. this.standardXHRResponse(
  763. this.requests[0],
  764. '#EXTM3U\n' +
  765. '#EXT-X-STREAM-INF:BANDWIDTH=50\n' +
  766. 'mediaLow.m3u8\n' +
  767. '#EXT-X-STREAM-INF:BANDWIDTH=240000\n' +
  768. 'mediaNormal.m3u8\n' +
  769. '#EXT-X-STREAM-INF:BANDWIDTH=19280000000\n' +
  770. 'mediaHigh.m3u8\n'
  771. );
  772. assert.strictEqual(
  773. this.requests[0].url,
  774. 'manifest/master.m3u8',
  775. 'master playlist requested'
  776. );
  777. assert.strictEqual(
  778. this.requests[1].url,
  779. absoluteUrl('manifest/mediaLow.m3u8'),
  780. 'low bandwidth media playlist requested'
  781. );
  782. });
  783. QUnit.test('buffer checks are noops until a media playlist is ready', function(assert) {
  784. this.player.src({
  785. src: 'manifest/media.m3u8',
  786. type: 'application/vnd.apple.mpegurl'
  787. });
  788. this.clock.tick(1);
  789. openMediaSource(this.player, this.clock);
  790. this.clock.tick(10 * 1000);
  791. assert.strictEqual(1, this.requests.length, 'one request was made');
  792. assert.strictEqual(
  793. this.requests[0].url,
  794. 'manifest/media.m3u8',
  795. 'media playlist requested'
  796. );
  797. });
  798. QUnit.test('buffer checks are noops when only the master is ready', function(assert) {
  799. this.player.src({
  800. src: 'manifest/master.m3u8',
  801. type: 'application/vnd.apple.mpegurl'
  802. });
  803. this.clock.tick(1);
  804. openMediaSource(this.player, this.clock);
  805. // master
  806. this.standardXHRResponse(this.requests.shift());
  807. // media
  808. this.standardXHRResponse(this.requests.shift());
  809. // ignore any outstanding segment requests
  810. this.requests.length = 0;
  811. // load in a new playlist which will cause playlists.media() to be
  812. // undefined while it is being fetched
  813. this.player.src({
  814. src: 'manifest/master.m3u8',
  815. type: 'application/vnd.apple.mpegurl'
  816. });
  817. openMediaSource(this.player, this.clock);
  818. // respond with the master playlist but don't send the media playlist yet
  819. // force media1 to be requested
  820. this.player.tech_.hls.bandwidth = 1;
  821. // master
  822. this.standardXHRResponse(this.requests.shift());
  823. this.clock.tick(10 * 1000);
  824. assert.strictEqual(this.requests.length, 1, 'one request was made');
  825. assert.strictEqual(
  826. this.requests[0].url,
  827. absoluteUrl('manifest/media1.m3u8'),
  828. 'media playlist requested'
  829. );
  830. // verify stats
  831. assert.equal(this.player.tech_.hls.stats.bandwidth, 1, 'bandwidth set above');
  832. });
  833. QUnit.test('selects a playlist below the current bandwidth', function(assert) {
  834. this.player.src({
  835. src: 'manifest/master.m3u8',
  836. type: 'application/vnd.apple.mpegurl'
  837. });
  838. this.clock.tick(1);
  839. openMediaSource(this.player, this.clock);
  840. this.standardXHRResponse(this.requests[0]);
  841. // the default playlist has a really high bitrate
  842. this.player.tech_.hls.playlists.master.playlists[0].attributes.BANDWIDTH = 9e10;
  843. // playlist 1 has a very low bitrate
  844. this.player.tech_.hls.playlists.master.playlists[1].attributes.BANDWIDTH = 1;
  845. // but the detected client bandwidth is really low
  846. this.player.tech_.hls.bandwidth = 10;
  847. const playlist = this.player.tech_.hls.selectPlaylist();
  848. assert.strictEqual(
  849. playlist,
  850. this.player.tech_.hls.playlists.master.playlists[1],
  851. 'the low bitrate stream is selected'
  852. );
  853. // verify stats
  854. assert.equal(this.player.tech_.hls.stats.bandwidth, 10, 'bandwidth set above');
  855. });
  856. QUnit.test(
  857. 'selects a primary rendtion when there are multiple rendtions share same attributes',
  858. function(assert) {
  859. let playlist;
  860. this.player.src({
  861. src: 'manifest/master.m3u8',
  862. type: 'application/vnd.apple.mpegurl'
  863. });
  864. openMediaSource(this.player, this.clock);
  865. standardXHRResponse(this.requests[0]);
  866. // covers playlists with same bandwidth but different resolution and different bandwidth
  867. // but same resolution
  868. this.player.tech_.hls.playlists.master.playlists[0].attributes.BANDWIDTH = 528;
  869. this.player.tech_.hls.playlists.master.playlists[1].attributes.BANDWIDTH = 528;
  870. this.player.tech_.hls.playlists.master.playlists[2].attributes.BANDWIDTH = 728;
  871. this.player.tech_.hls.playlists.master.playlists[3].attributes.BANDWIDTH = 728;
  872. this.player.tech_.hls.bandwidth = 1000;
  873. playlist = this.player.tech_.hls.selectPlaylist();
  874. assert.strictEqual(
  875. playlist,
  876. this.player.tech_.hls.playlists.master.playlists[2],
  877. 'select the rendition with largest bandwidth and just-larger-than video player'
  878. );
  879. // verify stats
  880. assert.equal(this.player.tech_.hls.stats.bandwidth, 1000, 'bandwidth set above');
  881. // covers playlists share same bandwidth and resolutions
  882. this.player.tech_.hls.playlists.master.playlists[0].attributes.BANDWIDTH = 728;
  883. this.player.tech_.hls.playlists.master.playlists[0].attributes.RESOLUTION.width = 960;
  884. this.player.tech_.hls.playlists.master.playlists[0].attributes.RESOLUTION.height = 540;
  885. this.player.tech_.hls.playlists.master.playlists[1].attributes.BANDWIDTH = 728;
  886. this.player.tech_.hls.playlists.master.playlists[2].attributes.BANDWIDTH = 728;
  887. this.player.tech_.hls.playlists.master.playlists[2].attributes.RESOLUTION.width = 960;
  888. this.player.tech_.hls.playlists.master.playlists[2].attributes.RESOLUTION.height = 540;
  889. this.player.tech_.hls.playlists.master.playlists[3].attributes.BANDWIDTH = 728;
  890. this.player.tech_.hls.bandwidth = 1000;
  891. playlist = this.player.tech_.hls.selectPlaylist();
  892. assert.strictEqual(
  893. playlist,
  894. this.player.tech_.hls.playlists.master.playlists[0],
  895. 'the primary rendition is selected'
  896. );
  897. }
  898. );
  899. QUnit.test('allows initial bandwidth to be provided', function(assert) {
  900. this.player.src({
  901. src: 'manifest/master.m3u8',
  902. type: 'application/vnd.apple.mpegurl'
  903. });
  904. this.clock.tick(1);
  905. openMediaSource(this.player, this.clock);
  906. this.player.tech_.hls.bandwidth = 500;
  907. this.requests[0].bandwidth = 1;
  908. this.requests.shift().respond(
  909. 200, null,
  910. '#EXTM3U\n' +
  911. '#EXT-X-PLAYLIST-TYPE:VOD\n' +
  912. '#EXT-X-TARGETDURATION:10\n'
  913. );
  914. assert.equal(
  915. this.player.tech_.hls.bandwidth,
  916. 500,
  917. 'prefers user-specified initial bandwidth'
  918. );
  919. // verify stats
  920. assert.equal(this.player.tech_.hls.stats.bandwidth, 500, 'bandwidth set above');
  921. });
  922. QUnit.test('raises the minimum bitrate for a stream proportionially', function(assert) {
  923. this.player.src({
  924. src: 'manifest/master.m3u8',
  925. type: 'application/vnd.apple.mpegurl'
  926. });
  927. this.clock.tick(1);
  928. openMediaSource(this.player, this.clock);
  929. this.standardXHRResponse(this.requests[0]);
  930. // the default playlist's bandwidth + 10% is assert.equal to the current bandwidth
  931. this.player.tech_.hls.playlists.master.playlists[0].attributes.BANDWIDTH = 10;
  932. this.player.tech_.hls.bandwidth = 11;
  933. // 9.9 * 1.1 < 11
  934. this.player.tech_.hls.playlists.master.playlists[1].attributes.BANDWIDTH = 9.9;
  935. const playlist = this.player.tech_.hls.selectPlaylist();
  936. assert.strictEqual(
  937. playlist,
  938. this.player.tech_.hls.playlists.master.playlists[1],
  939. 'a lower bitrate stream is selected'
  940. );
  941. // verify stats
  942. assert.equal(this.player.tech_.hls.stats.bandwidth, 11, 'bandwidth set above');
  943. });
  944. QUnit.test('uses the lowest bitrate if no other is suitable', function(assert) {
  945. this.player.src({
  946. src: 'manifest/master.m3u8',
  947. type: 'application/vnd.apple.mpegurl'
  948. });
  949. this.clock.tick(1);
  950. openMediaSource(this.player, this.clock);
  951. this.standardXHRResponse(this.requests[0]);
  952. // the lowest bitrate playlist is much greater than 1b/s
  953. this.player.tech_.hls.bandwidth = 1;
  954. const playlist = this.player.tech_.hls.selectPlaylist();
  955. // playlist 1 has the lowest advertised bitrate
  956. assert.strictEqual(
  957. playlist,
  958. this.player.tech_.hls.playlists.master.playlists[1],
  959. 'the lowest bitrate stream is selected'
  960. );
  961. // verify stats
  962. assert.equal(this.player.tech_.hls.stats.bandwidth, 1, 'bandwidth set above');
  963. });
  964. QUnit.test('selects the correct rendition by tech dimensions', function(assert) {
  965. let playlist;
  966. this.player.src({
  967. src: 'manifest/master.m3u8',
  968. type: 'application/vnd.apple.mpegurl'
  969. });
  970. this.clock.tick(1);
  971. openMediaSource(this.player, this.clock);
  972. this.standardXHRResponse(this.requests[0]);
  973. const hls = this.player.tech_.hls;
  974. this.player.width(640);
  975. this.player.height(360);
  976. hls.bandwidth = 3000000;
  977. playlist = hls.selectPlaylist();
  978. assert.deepEqual(
  979. playlist.attributes.RESOLUTION,
  980. {width: 960, height: 540},
  981. 'should return the correct resolution by tech dimensions'
  982. );
  983. assert.equal(
  984. playlist.attributes.BANDWIDTH,
  985. 1928000,
  986. 'should have the expected bandwidth in case of multiple'
  987. );
  988. this.player.width(1920);
  989. this.player.height(1080);
  990. hls.bandwidth = 3000000;
  991. playlist = hls.selectPlaylist();
  992. assert.deepEqual(
  993. playlist.attributes.RESOLUTION,
  994. {width: 960, height: 540},
  995. 'should return the correct resolution by tech dimensions'
  996. );
  997. assert.equal(
  998. playlist.attributes.BANDWIDTH,
  999. 1928000,
  1000. 'should have the expected bandwidth in case of multiple'
  1001. );
  1002. this.player.width(396);
  1003. this.player.height(224);
  1004. playlist = hls.selectPlaylist();
  1005. assert.deepEqual(
  1006. playlist.attributes.RESOLUTION,
  1007. {width: 396, height: 224},
  1008. 'should return the correct resolution by ' +
  1009. 'tech dimensions, if exact match'
  1010. );
  1011. assert.equal(
  1012. playlist.attributes.BANDWIDTH,
  1013. 440000,
  1014. 'should have the expected bandwidth in case of multiple, if exact match'
  1015. );
  1016. this.player.width(395);
  1017. this.player.height(222);
  1018. playlist = this.player.tech_.hls.selectPlaylist();
  1019. assert.deepEqual(
  1020. playlist.attributes.RESOLUTION,
  1021. {width: 396, height: 224},
  1022. 'should return the next larger resolution by tech dimensions, ' +
  1023. 'if no exact match exists'
  1024. );
  1025. assert.equal(
  1026. playlist.attributes.BANDWIDTH,
  1027. 440000,
  1028. 'should have the expected bandwidth in case of multiple, if exact match'
  1029. );
  1030. // verify stats
  1031. assert.equal(this.player.tech_.hls.stats.bandwidth, 3000000, 'bandwidth set above');
  1032. });
  1033. QUnit.test('selects the highest bitrate playlist when the player dimensions are ' +
  1034. 'larger than any of the variants', function(assert) {
  1035. this.player.src({
  1036. src: 'manifest/master.m3u8',
  1037. type: 'application/vnd.apple.mpegurl'
  1038. });
  1039. this.clock.tick(1);
  1040. openMediaSource(this.player, this.clock);
  1041. // master
  1042. this.requests.shift().respond(
  1043. 200, null,
  1044. '#EXTM3U\n' +
  1045. '#EXT-X-STREAM-INF:BANDWIDTH=1000,RESOLUTION=2x1\n' +
  1046. 'media.m3u8\n' +
  1047. '#EXT-X-STREAM-INF:BANDWIDTH=1,RESOLUTION=1x1\n' +
  1048. 'media1.m3u8\n'
  1049. );
  1050. // media
  1051. this.standardXHRResponse(this.requests.shift());
  1052. this.player.tech_.hls.bandwidth = 1e10;
  1053. this.player.width(1024);
  1054. this.player.height(768);
  1055. const playlist = this.player.tech_.hls.selectPlaylist();
  1056. assert.equal(
  1057. playlist.attributes.BANDWIDTH,
  1058. 1000,
  1059. 'selected the highest bandwidth variant'
  1060. );
  1061. // verify stats
  1062. assert.equal(this.player.tech_.hls.stats.bandwidth, 1e10, 'bandwidth set above');
  1063. });
  1064. QUnit.test('filters playlists that are currently excluded', function(assert) {
  1065. let playlist;
  1066. this.player.src({
  1067. src: 'manifest/master.m3u8',
  1068. type: 'application/vnd.apple.mpegurl'
  1069. });
  1070. this.clock.tick(1);
  1071. openMediaSource(this.player, this.clock);
  1072. this.player.tech_.hls.bandwidth = 1e10;
  1073. // master
  1074. this.requests.shift().respond(
  1075. 200, null,
  1076. '#EXTM3U\n' +
  1077. '#EXT-X-STREAM-INF:BANDWIDTH=1000\n' +
  1078. 'media.m3u8\n' +
  1079. '#EXT-X-STREAM-INF:BANDWIDTH=1\n' +
  1080. 'media1.m3u8\n'
  1081. );
  1082. // media
  1083. this.standardXHRResponse(this.requests.shift());
  1084. // exclude the current playlist
  1085. this.player.tech_.hls.playlists.master.playlists[0].excludeUntil = +new Date() + 1000;
  1086. playlist = this.player.tech_.hls.selectPlaylist();
  1087. assert.equal(
  1088. playlist,
  1089. this.player.tech_.hls.playlists.master.playlists[1],
  1090. 'respected exclusions'
  1091. );
  1092. // timeout the exclusion
  1093. this.clock.tick(1000);
  1094. playlist = this.player.tech_.hls.selectPlaylist();
  1095. assert.equal(
  1096. playlist,
  1097. this.player.tech_.hls.playlists.master.playlists[0],
  1098. 'expired the exclusion'
  1099. );
  1100. // verify stats
  1101. assert.equal(this.player.tech_.hls.stats.bandwidth, 1e10, 'bandwidth set above');
  1102. });
  1103. QUnit.test('does not blacklist compatible H.264 codec strings', function(assert) {
  1104. this.player.src({
  1105. src: 'manifest/master.m3u8',
  1106. type: 'application/vnd.apple.mpegurl'
  1107. });
  1108. this.clock.tick(1);
  1109. openMediaSource(this.player, this.clock);
  1110. this.player.tech_.hls.bandwidth = 1;
  1111. // master
  1112. this.requests.shift()
  1113. .respond(
  1114. 200, null,
  1115. '#EXTM3U\n' +
  1116. '#EXT-X-STREAM-INF:BANDWIDTH=1,CODECS="avc1.4d400d,mp4a.40.5"\n' +
  1117. 'media.m3u8\n' +
  1118. '#EXT-X-STREAM-INF:BANDWIDTH=10,CODECS="avc1.4d400f,mp4a.40.5"\n' +
  1119. 'media1.m3u8\n'
  1120. );
  1121. // media
  1122. this.standardXHRResponse(this.requests.shift());
  1123. const master = this.player.tech_.hls.playlists.master;
  1124. assert.strictEqual(
  1125. typeof master.playlists[0].excludeUntil,
  1126. 'undefined',
  1127. 'did not blacklist'
  1128. );
  1129. assert.strictEqual(
  1130. typeof master.playlists[1].excludeUntil,
  1131. 'undefined',
  1132. 'did not blacklist'
  1133. );
  1134. // verify stats
  1135. assert.equal(this.player.tech_.hls.stats.bandwidth, 1, 'bandwidth set above');
  1136. });
  1137. QUnit.test('does not blacklist compatible AAC codec strings', function(assert) {
  1138. this.player.src({
  1139. src: 'manifest/master.m3u8',
  1140. type: 'application/vnd.apple.mpegurl'
  1141. });
  1142. this.clock.tick(1);
  1143. openMediaSource(this.player, this.clock);
  1144. // master
  1145. this.requests.shift()
  1146. .respond(
  1147. 200, null,
  1148. '#EXTM3U\n' +
  1149. '#EXT-X-STREAM-INF:BANDWIDTH=1,CODECS="avc1.4d400d,mp4a.40.2"\n' +
  1150. 'media.m3u8\n' +
  1151. '#EXT-X-STREAM-INF:BANDWIDTH=10,CODECS="avc1.4d400d,not-an-audio-codec"\n' +
  1152. 'media1.m3u8\n'
  1153. );
  1154. // media
  1155. this.standardXHRResponse(this.requests.shift());
  1156. const master = this.player.tech_.hls.playlists.master;
  1157. assert.strictEqual(
  1158. typeof master.playlists[0].excludeUntil,
  1159. 'undefined',
  1160. 'did not blacklist mp4a.40.2'
  1161. );
  1162. assert.strictEqual(
  1163. master.playlists[1].excludeUntil,
  1164. Infinity,
  1165. 'blacklisted invalid audio codec'
  1166. );
  1167. });
  1168. QUnit.test('cancels outstanding XHRs when seeking', function(assert) {
  1169. this.player.src({
  1170. src: 'manifest/media.m3u8',
  1171. type: 'application/vnd.apple.mpegurl'
  1172. });
  1173. this.clock.tick(1);
  1174. openMediaSource(this.player, this.clock);
  1175. this.standardXHRResponse(this.requests[0]);
  1176. this.player.tech_.hls.media = {
  1177. segments: [{
  1178. uri: '0.ts',
  1179. duration: 10
  1180. }, {
  1181. uri: '1.ts',
  1182. duration: 10
  1183. }]
  1184. };
  1185. // attempt to seek while the download is in progress
  1186. this.player.currentTime(7);
  1187. this.clock.tick(2);
  1188. assert.ok(this.requests[1].aborted, 'XHR aborted');
  1189. assert.strictEqual(this.requests.length, 3, 'opened new XHR');
  1190. });
  1191. QUnit.test('does not abort segment loading for in-buffer seeking', function(assert) {
  1192. this.player.src({
  1193. src: 'manifest/media.m3u8',
  1194. type: 'application/vnd.apple.mpegurl'
  1195. });
  1196. this.clock.tick(1);
  1197. openMediaSource(this.player, this.clock);
  1198. this.standardXHRResponse(this.requests.shift());
  1199. this.player.tech_.buffered = function() {
  1200. return videojs.createTimeRange(0, 20);
  1201. };
  1202. this.player.tech_.setCurrentTime(11);
  1203. this.clock.tick(1);
  1204. assert.equal(this.requests.length, 1, 'did not abort the outstanding request');
  1205. });
  1206. QUnit.test('unsupported playlist should not be re-included when excluding last playlist', function(assert) {
  1207. this.player.src({
  1208. src: 'manifest/master.m3u8',
  1209. type: 'application/vnd.apple.mpegurl'
  1210. });
  1211. this.clock.tick(1);
  1212. openMediaSource(this.player, this.clock);
  1213. this.player.tech_.hls.bandwidth = 1;
  1214. // master
  1215. this.requests.shift()
  1216. .respond(
  1217. 200, null,
  1218. '#EXTM3U\n' +
  1219. '#EXT-X-STREAM-INF:BANDWIDTH=1,CODECS="avc1.4d400d,mp4a.40.2"\n' +
  1220. 'media.m3u8\n' +
  1221. '#EXT-X-STREAM-INF:BANDWIDTH=10,CODECS="avc1.4d400d,not-an-audio-codec"\n' +
  1222. 'media1.m3u8\n'
  1223. );
  1224. // media
  1225. this.standardXHRResponse(this.requests.shift());
  1226. const master = this.player.tech_.hls.playlists.master;
  1227. const media = this.player.tech_.hls.playlists.media_;
  1228. // segment
  1229. this.requests.shift().respond(400);
  1230. assert.ok(master.playlists[0].excludeUntil > 0, 'original media excluded for some time');
  1231. assert.strictEqual(
  1232. master.playlists[1].excludeUntil,
  1233. Infinity,
  1234. 'blacklisted invalid audio codec'
  1235. );
  1236. assert.equal(this.env.log.warn.calls, 2, 'warning logged for blacklist');
  1237. assert.equal(
  1238. this.env.log.warn.args[0],
  1239. 'Removing all playlists from the blacklist because the last rendition is about to be blacklisted.',
  1240. 'log generic error message'
  1241. );
  1242. });
  1243. QUnit.test('segment 404 should trigger blacklisting of media', function(assert) {
  1244. this.player.src({
  1245. src: 'manifest/master.m3u8',
  1246. type: 'application/vnd.apple.mpegurl'
  1247. });
  1248. this.clock.tick(1);
  1249. openMediaSource(this.player, this.clock);
  1250. this.player.tech_.hls.bandwidth = 20000;
  1251. // master
  1252. this.standardXHRResponse(this.requests[0]);
  1253. // media
  1254. this.standardXHRResponse(this.requests[1]);
  1255. const media = this.player.tech_.hls.playlists.media_;
  1256. // segment
  1257. this.requests[2].respond(400);
  1258. assert.ok(media.excludeUntil > 0, 'original media blacklisted for some time');
  1259. assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist');
  1260. // verify stats
  1261. assert.equal(this.player.tech_.hls.stats.bandwidth, 20000, 'bandwidth set above');
  1262. });
  1263. QUnit.test('playlist 404 should blacklist media', function(assert) {
  1264. let media;
  1265. let url;
  1266. let blacklistplaylist = 0;
  1267. let retryplaylist = 0;
  1268. let hlsRenditionBlacklistedEvents = 0;
  1269. this.player.src({
  1270. src: 'manifest/master.m3u8',
  1271. type: 'application/vnd.apple.mpegurl'
  1272. });
  1273. this.clock.tick(1);
  1274. openMediaSource(this.player, this.clock);
  1275. this.player.tech_.on('blacklistplaylist', () => blacklistplaylist++);
  1276. this.player.tech_.on('retryplaylist', () => retryplaylist++);
  1277. this.player.tech_.on('usage', (event) => {
  1278. if (event.name === 'hls-rendition-blacklisted') {
  1279. hlsRenditionBlacklistedEvents++;
  1280. }
  1281. });
  1282. this.player.tech_.hls.bandwidth = 1e10;
  1283. // master
  1284. this.requests[0].respond(
  1285. 200, null,
  1286. '#EXTM3U\n' +
  1287. '#EXT-X-STREAM-INF:BANDWIDTH=1000\n' +
  1288. 'media.m3u8\n' +
  1289. '#EXT-X-STREAM-INF:BANDWIDTH=1\n' +
  1290. 'media1.m3u8\n'
  1291. );
  1292. assert.equal(
  1293. typeof this.player.tech_.hls.playlists.media_,
  1294. 'undefined',
  1295. 'no media is initially set'
  1296. );
  1297. assert.equal(blacklistplaylist, 0, 'there is no blacklisted playlist');
  1298. assert.equal(
  1299. hlsRenditionBlacklistedEvents,
  1300. 0,
  1301. 'no hls-rendition-blacklisted event was fired'
  1302. );
  1303. // media
  1304. this.requests[1].respond(404);
  1305. url = this.requests[1].url.slice(this.requests[1].url.lastIndexOf('/') + 1);
  1306. media = this.player.tech_.hls.playlists.master.playlists[url];
  1307. assert.ok(media.excludeUntil > 0, 'original media blacklisted for some time');
  1308. assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist');
  1309. assert.equal(
  1310. this.env.log.warn.args[0],
  1311. 'Problem encountered with the current playlist. HLS playlist request error at URL: media.m3u8. Switching to another playlist.',
  1312. 'log generic error message'
  1313. );
  1314. assert.equal(blacklistplaylist, 1, 'there is one blacklisted playlist');
  1315. assert.equal(
  1316. hlsRenditionBlacklistedEvents,
  1317. 1,
  1318. 'an hls-rendition-blacklisted event was fired'
  1319. );
  1320. assert.equal(retryplaylist, 0, 'haven\'t retried any playlist');
  1321. // request for the final available media
  1322. this.requests[2].respond(404);
  1323. url = this.requests[2].url.slice(this.requests[2].url.lastIndexOf('/') + 1);
  1324. media = this.player.tech_.hls.playlists.master.playlists[url];
  1325. assert.ok(media.excludeUntil > 0, 'second media was blacklisted after playlist 404');
  1326. assert.equal(this.env.log.warn.calls, 2, 'warning logged for blacklist');
  1327. assert.equal(
  1328. this.env.log.warn.args[1],
  1329. 'Removing all playlists from the blacklist because the last rendition is about to be blacklisted.',
  1330. 'log generic error message'
  1331. );
  1332. assert.equal(
  1333. this.env.log.warn.args[2],
  1334. 'Problem encountered with the current playlist. HLS playlist request error at URL: media1.m3u8. ' +
  1335. 'Switching to another playlist.',
  1336. 'log generic error message'
  1337. );
  1338. assert.equal(retryplaylist, 1, 'fired a retryplaylist event');
  1339. assert.equal(blacklistplaylist, 2, 'media1 is blacklisted');
  1340. this.clock.tick(2 * 1000);
  1341. // no new request was made since it hasn't been half the segment duration
  1342. assert.strictEqual(3, this.requests.length, 'no new request was made');
  1343. this.clock.tick(3 * 1000);
  1344. // loading the first playlist since the blacklist duration was cleared
  1345. // when half the segment duaration passed
  1346. assert.strictEqual(4, this.requests.length, 'one more request was made');
  1347. url = this.requests[3].url.slice(this.requests[3].url.lastIndexOf('/') + 1);
  1348. media = this.player.tech_.hls.playlists.master.playlists[url];
  1349. // the first media was unblacklisted after a refresh delay
  1350. assert.ok(!media.excludeUntil, 'removed first media from blacklist');
  1351. assert.strictEqual(
  1352. this.requests[3].url,
  1353. absoluteUrl('manifest/media.m3u8'),
  1354. 'media playlist requested'
  1355. );
  1356. // verify stats
  1357. assert.equal(this.player.tech_.hls.stats.bandwidth, 1e10, 'bandwidth set above');
  1358. });
  1359. QUnit.test('blacklists playlist if it has stopped being updated', function(assert) {
  1360. let playliststuck = 0;
  1361. this.player.src({
  1362. src: 'master.m3u8',
  1363. type: 'application/vnd.apple.mpegurl'
  1364. });
  1365. openMediaSource(this.player, this.clock);
  1366. this.player.tech_.triggerReady();
  1367. this.standardXHRResponse(this.requests.shift());
  1368. this.player.tech_.hls.masterPlaylistController_.seekable = function() {
  1369. return videojs.createTimeRange(90, 130);
  1370. };
  1371. this.player.tech_.setCurrentTime(170);
  1372. this.player.tech_.buffered = function() {
  1373. return videojs.createTimeRange(0, 170);
  1374. };
  1375. Hls.Playlist.playlistEnd = function() {
  1376. return 170;
  1377. };
  1378. this.player.tech_.on('playliststuck', () => playliststuck++);
  1379. this.requests.shift().respond(
  1380. 200, null,
  1381. '#EXTM3U\n' +
  1382. '#EXT-X-MEDIA-SEQUENCE:16\n' +
  1383. '#EXTINF:10,\n' +
  1384. '16.ts\n'
  1385. );
  1386. assert.ok(
  1387. !this.player.tech_.hls.playlists.media().excludeUntil,
  1388. 'playlist was not blacklisted'
  1389. );
  1390. assert.equal(this.env.log.warn.calls, 0, 'no warning logged for blacklist');
  1391. assert.equal(playliststuck, 0, 'there is no stuck playlist');
  1392. this.player.tech_.trigger('play');
  1393. this.player.tech_.trigger('playing');
  1394. // trigger a refresh
  1395. this.clock.tick(10 * 1000);
  1396. this.requests.shift().respond(
  1397. 200, null,
  1398. '#EXTM3U\n' +
  1399. '#EXT-X-MEDIA-SEQUENCE:16\n' +
  1400. '#EXTINF:10,\n' +
  1401. '16.ts\n'
  1402. );
  1403. assert.ok(
  1404. this.player.tech_.hls.playlists.media().excludeUntil > 0,
  1405. 'playlist blacklisted for some time'
  1406. );
  1407. assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist');
  1408. assert.equal(
  1409. this.env.log.warn.args[0],
  1410. 'Problem encountered with the current playlist. ' +
  1411. 'Playlist no longer updating. Switching to another playlist.',
  1412. 'log specific error message for not updated playlist'
  1413. );
  1414. assert.equal(playliststuck, 1, 'there is one stuck playlist');
  1415. });
  1416. QUnit.test('never blacklist the playlist if it is the only playlist', function(assert) {
  1417. this.player.src({
  1418. src: 'manifest/media.m3u8',
  1419. type: 'application/vnd.apple.mpegurl'
  1420. });
  1421. openMediaSource(this.player, this.clock);
  1422. this.requests.shift().respond(
  1423. 200, null,
  1424. '#EXTM3U\n' +
  1425. '#EXTINF:10,\n' +
  1426. '0.ts\n'
  1427. );
  1428. this.clock.tick(10 * 1000);
  1429. this.requests.shift().respond(404);
  1430. const media = this.player.tech_.hls.playlists.media();
  1431. // media wasn't blacklisted because it's the only rendition
  1432. assert.ok(!media.excludeUntil, 'media was not blacklisted after playlist 404');
  1433. assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist');
  1434. assert.equal(
  1435. this.env.log.warn.args[0],
  1436. 'Problem encountered with the current playlist. ' +
  1437. 'Trying again since it is the only playlist.',
  1438. 'log specific error message for the only playlist'
  1439. );
  1440. });
  1441. QUnit.test(
  1442. 'error on the first playlist request does not trigger an error when there is master ' +
  1443. 'playlist with only one media playlist',
  1444. function(assert) {
  1445. this.player.src({
  1446. src: 'manifest/master.m3u8',
  1447. type: 'application/vnd.apple.mpegurl'
  1448. });
  1449. openMediaSource(this.player, this.clock);
  1450. this.requests[0]
  1451. .respond(
  1452. 200, null,
  1453. '#EXTM3U\n' +
  1454. '#EXT-X-STREAM-INF:BANDWIDTH=1000\n' +
  1455. 'media.m3u8\n'
  1456. );
  1457. this.requests[1].respond(404);
  1458. const url = this.requests[1].url.slice(this.requests[1].url.lastIndexOf('/') + 1);
  1459. const media = this.player.tech_.hls.playlists.master.playlists[url];
  1460. // media wasn't blacklisted because it's the only rendition
  1461. assert.ok(!media.excludeUntil, 'media was not blacklisted after playlist 404');
  1462. assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist');
  1463. assert.equal(
  1464. this.env.log.warn.args[0],
  1465. 'Problem encountered with the current playlist. ' +
  1466. 'Trying again since it is the only playlist.',
  1467. 'log specific error message for the onlyplaylist'
  1468. );
  1469. }
  1470. );
  1471. QUnit.test('seeking in an empty playlist is a non-erroring noop', function(assert) {
  1472. this.player.src({
  1473. src: 'manifest/empty-live.m3u8',
  1474. type: 'application/vnd.apple.mpegurl'
  1475. });
  1476. this.clock.tick(1);
  1477. openMediaSource(this.player, this.clock);
  1478. this.requests.shift().respond(200, null, '#EXTM3U\n');
  1479. const requestsLength = this.requests.length;
  1480. this.player.tech_.setCurrentTime(183);
  1481. this.clock.tick(1);
  1482. assert.equal(this.requests.length, requestsLength, 'made no additional requests');
  1483. });
  1484. QUnit.test('fire loadedmetadata once we successfully load a playlist', function(assert) {
  1485. let count = 0;
  1486. this.player.src({
  1487. src: 'manifest/master.m3u8',
  1488. type: 'application/vnd.apple.mpegurl'
  1489. });
  1490. this.clock.tick(1);
  1491. openMediaSource(this.player, this.clock);
  1492. const hls = this.player.tech_.hls;
  1493. hls.bandwidth = 20000;
  1494. hls.masterPlaylistController_.masterPlaylistLoader_.on('loadedmetadata', function() {
  1495. count += 1;
  1496. });
  1497. // master
  1498. this.standardXHRResponse(this.requests.shift());
  1499. assert.equal(
  1500. count, 0,
  1501. 'loadedMedia not triggered before requesting playlist'
  1502. );
  1503. // media
  1504. this.requests.shift().respond(404);
  1505. assert.equal(
  1506. count, 0,
  1507. 'loadedMedia not triggered after playlist 404'
  1508. );
  1509. assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist');
  1510. // media
  1511. this.standardXHRResponse(this.requests.shift());
  1512. assert.equal(
  1513. count, 1,
  1514. 'loadedMedia triggered after successful recovery from 404'
  1515. );
  1516. // verify stats
  1517. assert.equal(this.player.tech_.hls.stats.bandwidth, 20000, 'bandwidth set above');
  1518. });
  1519. QUnit.test('sets seekable and duration for live playlists', function(assert) {
  1520. this.player.src({
  1521. src: 'http://example.com/manifest/missingEndlist.m3u8',
  1522. type: 'application/vnd.apple.mpegurl'
  1523. });
  1524. this.clock.tick(1);
  1525. openMediaSource(this.player, this.clock);
  1526. // since the safe live end will be 3 target durations back, in order for there to be a
  1527. // positive seekable end, there should be at least 4 segments
  1528. this.requests.shift().respond(200, null, `
  1529. #EXTM3U
  1530. #EXT-X-TARGETDURATION:5
  1531. #EXTINF:5
  1532. 0.ts
  1533. #EXTINF:5
  1534. 1.ts
  1535. #EXTINF:5
  1536. 2.ts
  1537. #EXTINF:5
  1538. 3.ts
  1539. `);
  1540. assert.equal(this.player.vhs.seekable().length, 1, 'set one seekable range');
  1541. assert.equal(this.player.vhs.seekable().start(0), 0, 'set seekable start');
  1542. assert.equal(this.player.vhs.seekable().end(0), 5, 'set seekable end');
  1543. assert.strictEqual(
  1544. this.player.vhs.duration(),
  1545. Infinity,
  1546. 'duration reported by VHS is infinite'
  1547. );
  1548. assert.strictEqual(
  1549. this.player.vhs.mediaSource.duration,
  1550. this.player.vhs.seekable().end(0),
  1551. 'duration on the mediaSource is seekable end'
  1552. );
  1553. });
  1554. QUnit.test('live playlist starts with correct currentTime value', function(assert) {
  1555. this.player.src({
  1556. src: 'http://example.com/manifest/liveStart30sBefore.m3u8',
  1557. type: 'application/vnd.apple.mpegurl'
  1558. });
  1559. this.clock.tick(1);
  1560. openMediaSource(this.player, this.clock);
  1561. this.standardXHRResponse(this.requests[0]);
  1562. let currentTime = 0;
  1563. this.player.tech_.setCurrentTime = (ct) => {
  1564. currentTime = ct;
  1565. };
  1566. this.player.tech_.readyState = () => 4;
  1567. this.player.tech_.hls.playlists.trigger('loadedmetadata');
  1568. this.player.tech_.paused = function() {
  1569. return false;
  1570. };
  1571. this.player.tech_.trigger('play');
  1572. this.clock.tick(1);
  1573. const media = this.player.tech_.hls.playlists.media();
  1574. assert.strictEqual(
  1575. currentTime,
  1576. Hls.Playlist.seekable(media).end(0),
  1577. 'currentTime is updated at playback'
  1578. );
  1579. });
  1580. QUnit.test(
  1581. 'estimates seekable ranges for live streams that have been paused for a long time',
  1582. function(assert) {
  1583. this.player.src({
  1584. src: 'http://example.com/manifest/liveStart30sBefore.m3u8',
  1585. type: 'application/vnd.apple.mpegurl'
  1586. });
  1587. this.clock.tick(1);
  1588. openMediaSource(this.player, this.clock);
  1589. this.standardXHRResponse(this.requests.shift());
  1590. this.player.tech_.hls.playlists.media().mediaSequence = 172;
  1591. this.player.tech_.hls.playlists.media().syncInfo = {
  1592. mediaSequence: 130,
  1593. time: 80
  1594. };
  1595. this.player.tech_.hls.masterPlaylistController_.onSyncInfoUpdate_();
  1596. assert.equal(
  1597. this.player.seekable().start(0),
  1598. 500,
  1599. 'offset the seekable start'
  1600. );
  1601. }
  1602. );
  1603. QUnit.test('resets the time to the live point when resuming a live stream after a ' +
  1604. 'long break', function(assert) {
  1605. let seekTarget;
  1606. this.player.src({
  1607. src: 'live0.m3u8',
  1608. type: 'application/vnd.apple.mpegurl'
  1609. });
  1610. this.clock.tick(1);
  1611. openMediaSource(this.player, this.clock);
  1612. this.requests.shift().respond(
  1613. 200, null,
  1614. '#EXTM3U\n' +
  1615. '#EXT-X-MEDIA-SEQUENCE:16\n' +
  1616. '#EXTINF:10,\n' +
  1617. '16.ts\n'
  1618. );
  1619. // mock out the player to simulate a live stream that has been
  1620. // playing for awhile
  1621. this.player.tech_.hls.seekable = function() {
  1622. return videojs.createTimeRange(160, 170);
  1623. };
  1624. this.player.tech_.setCurrentTime = function(time) {
  1625. if (typeof time !== 'undefined') {
  1626. seekTarget = time;
  1627. }
  1628. };
  1629. this.player.tech_.played = function() {
  1630. return videojs.createTimeRange(120, 170);
  1631. };
  1632. this.player.tech_.trigger('playing');
  1633. const seekable = this.player.seekable();
  1634. this.player.tech_.trigger('play');
  1635. assert.equal(seekTarget, seekable.end(seekable.length - 1), 'seeked to live point');
  1636. this.player.tech_.trigger('seeked');
  1637. });
  1638. QUnit.test(
  1639. 'reloads out-of-date live playlists when switching variants',
  1640. function(assert) {
  1641. const oldManifest = testDataManifests['variant-update'];
  1642. this.player.src({
  1643. src: 'http://example.com/master.m3u8',
  1644. type: 'application/vnd.apple.mpegurl'
  1645. });
  1646. this.clock.tick(1);
  1647. openMediaSource(this.player, this.clock);
  1648. this.player.tech_.hls.master = {
  1649. playlists: [{
  1650. mediaSequence: 15,
  1651. segments: [1, 1, 1]
  1652. }, {
  1653. uri: 'http://example.com/variant-update.m3u8',
  1654. mediaSequence: 0,
  1655. segments: [1, 1]
  1656. }]
  1657. };
  1658. // playing segment 15 on playlist zero
  1659. this.player.tech_.hls.media = this.player.tech_.hls.master.playlists[0];
  1660. this.player.mediaIndex = 1;
  1661. testDataManifests['variant-update'] = '#EXTM3U\n' +
  1662. '#EXT-X-MEDIA-SEQUENCE:16\n' +
  1663. '#EXTINF:10,\n' +
  1664. '16.ts\n' +
  1665. '#EXTINF:10,\n' +
  1666. '17.ts\n';
  1667. // switch playlists
  1668. this.player.tech_.hls.selectPlaylist = function() {
  1669. return this.player.tech_.hls.master.playlists[1];
  1670. };
  1671. // timeupdate downloads segment 16 then switches playlists
  1672. this.player.trigger('timeupdate');
  1673. assert.strictEqual(this.player.mediaIndex, 1, 'mediaIndex points at the next segment');
  1674. testDataManifests['variant-update'] = oldManifest;
  1675. }
  1676. );
  1677. QUnit.test(
  1678. 'if withCredentials global option is used, withCredentials is set on the XHR object',
  1679. function(assert) {
  1680. const hlsOptions = videojs.options.hls;
  1681. this.player.dispose();
  1682. videojs.options.hls = {
  1683. withCredentials: true
  1684. };
  1685. this.player = createPlayer();
  1686. this.player.src({
  1687. src: 'http://example.com/media.m3u8',
  1688. type: 'application/vnd.apple.mpegurl'
  1689. });
  1690. this.clock.tick(1);
  1691. openMediaSource(this.player, this.clock);
  1692. assert.ok(
  1693. this.requests[0].withCredentials,
  1694. 'with credentials should be set to true if that option is passed in'
  1695. );
  1696. videojs.options.hls = hlsOptions;
  1697. }
  1698. );
  1699. QUnit.test('if handleManifestRedirects global option is used, it should be passed to PlaylistLoader', function(assert) {
  1700. const hlsOptions = videojs.options.hls;
  1701. this.player.dispose();
  1702. videojs.options.hls = {
  1703. handleManifestRedirects: true
  1704. };
  1705. this.player = createPlayer();
  1706. this.player.src({
  1707. src: 'http://example.com/media.m3u8',
  1708. type: 'application/vnd.apple.mpegurl'
  1709. });
  1710. this.clock.tick(1);
  1711. assert.ok(
  1712. this.player.tech_.hls.masterPlaylistController_.masterPlaylistLoader_.handleManifestRedirects,
  1713. 'handleManifestRedirects is set correctly'
  1714. );
  1715. videojs.options.hls = hlsOptions;
  1716. });
  1717. QUnit.test(
  1718. 'if handlePartialData global option is used, it is set on audio/main loader but not subtitle',
  1719. function(assert) {
  1720. const hlsOptions = videojs.options.hls;
  1721. this.player.dispose();
  1722. videojs.options.hls = {
  1723. handlePartialData: true
  1724. };
  1725. this.player = createPlayer();
  1726. this.player.src({
  1727. src: 'http://example.com/media.m3u8',
  1728. type: 'application/vnd.apple.mpegurl'
  1729. });
  1730. this.clock.tick(1);
  1731. openMediaSource(this.player, this.clock);
  1732. const {mainSegmentLoader_, subtitleSegmentLoader_, audioSegmentLoader_} =
  1733. this.player.vhs.masterPlaylistController_;
  1734. assert.equal(mainSegmentLoader_.handlePartialData_, true, 'is set on main');
  1735. assert.equal(audioSegmentLoader_.handlePartialData_, true, 'is set on audio');
  1736. assert.equal(subtitleSegmentLoader_.handlePartialData_, false, 'is not set on subtitle');
  1737. videojs.options.hls = hlsOptions;
  1738. }
  1739. );
  1740. QUnit.test(
  1741. 'if handlePartialData source option is used, it is set on audio/main loader but not subtitle',
  1742. function(assert) {
  1743. const hlsOptions = videojs.options.hls;
  1744. this.player.dispose();
  1745. this.player = createPlayer();
  1746. this.player.src({
  1747. src: 'http://example.com/media.m3u8',
  1748. type: 'application/vnd.apple.mpegurl',
  1749. handlePartialData: true
  1750. });
  1751. this.clock.tick(1);
  1752. openMediaSource(this.player, this.clock);
  1753. const {mainSegmentLoader_, subtitleSegmentLoader_, audioSegmentLoader_} =
  1754. this.player.vhs.masterPlaylistController_;
  1755. assert.equal(mainSegmentLoader_.handlePartialData_, true, 'is set on main');
  1756. assert.equal(audioSegmentLoader_.handlePartialData_, true, 'is set on audio');
  1757. assert.equal(subtitleSegmentLoader_.handlePartialData_, false, 'is not set on subtitle');
  1758. videojs.options.hls = hlsOptions;
  1759. }
  1760. );
  1761. QUnit.test('the handlePartialData source option overrides the global default', function(assert) {
  1762. const hlsOptions = videojs.options.hls;
  1763. this.player.dispose();
  1764. videojs.options.hls = {
  1765. handlePartialData: true
  1766. };
  1767. this.player = createPlayer();
  1768. this.player.src({
  1769. src: 'http://example.com/media.m3u8',
  1770. type: 'application/vnd.apple.mpegurl',
  1771. handlePartialData: false
  1772. });
  1773. this.clock.tick(1);
  1774. openMediaSource(this.player, this.clock);
  1775. const {mainSegmentLoader_, subtitleSegmentLoader_, audioSegmentLoader_} =
  1776. this.player.vhs.masterPlaylistController_;
  1777. assert.equal(mainSegmentLoader_.handlePartialData_, false, 'is set on main');
  1778. assert.equal(audioSegmentLoader_.handlePartialData_, false, 'is set on audio');
  1779. assert.equal(subtitleSegmentLoader_.handlePartialData_, false, 'is not set on subtitle');
  1780. videojs.options.hls = hlsOptions;
  1781. });
  1782. QUnit.test('the handleManifestRedirects source option overrides the global default', function(assert) {
  1783. const hlsOptions = videojs.options.hls;
  1784. this.player.dispose();
  1785. videojs.options.hls = {
  1786. handleManifestRedirects: true
  1787. };
  1788. this.player = createPlayer();
  1789. this.player.src({
  1790. src: 'http://example.com/media.m3u8',
  1791. type: 'application/vnd.apple.mpegurl',
  1792. handleManifestRedirects: false
  1793. });
  1794. this.clock.tick(1);
  1795. assert.notOk(
  1796. this.player.tech_.hls.masterPlaylistController_.masterPlaylistLoader_.handleManifestRedirects,
  1797. 'handleManifestRedirects is set correctly'
  1798. );
  1799. videojs.options.hls = hlsOptions;
  1800. });
  1801. QUnit.test('if handleManifestRedirects global option is used, it should be passed to DashPlaylistLoader', function(assert) {
  1802. const hlsOptions = videojs.options.hls;
  1803. this.player.dispose();
  1804. videojs.options.hls = {
  1805. handleManifestRedirects: true
  1806. };
  1807. this.player = createPlayer();
  1808. this.player.src({
  1809. src: 'http://example.com/media.mpd',
  1810. type: 'application/dash+xml'
  1811. });
  1812. this.clock.tick(1);
  1813. assert.ok(this.player.tech_.hls.masterPlaylistController_.masterPlaylistLoader_.handleManifestRedirects);
  1814. videojs.options.hls = hlsOptions;
  1815. });
  1816. QUnit.test('the handleManifestRedirects in DashPlaylistLoader option overrides the global default', function(assert) {
  1817. const hlsOptions = videojs.options.hls;
  1818. this.player.dispose();
  1819. videojs.options.hls = {
  1820. handleManifestRedirects: true
  1821. };
  1822. this.player = createPlayer();
  1823. this.player.src({
  1824. src: 'http://example.com/media.mpd',
  1825. type: 'application/dash+xml',
  1826. handleManifestRedirects: false
  1827. });
  1828. this.clock.tick(1);
  1829. assert.notOk(this.player.tech_.hls.masterPlaylistController_.masterPlaylistLoader_.handleManifestRedirects);
  1830. videojs.options.hls = hlsOptions;
  1831. });
  1832. QUnit.test('the withCredentials option overrides the global default', function(assert) {
  1833. const hlsOptions = videojs.options.hls;
  1834. this.player.dispose();
  1835. videojs.options.hls = {
  1836. withCredentials: true
  1837. };
  1838. this.player = createPlayer();
  1839. this.player.src({
  1840. src: 'http://example.com/media.m3u8',
  1841. type: 'application/vnd.apple.mpegurl',
  1842. withCredentials: false
  1843. });
  1844. this.clock.tick(1);
  1845. openMediaSource(this.player, this.clock);
  1846. assert.ok(
  1847. !this.requests[0].withCredentials,
  1848. 'with credentials should be set to false if if overrode global option'
  1849. );
  1850. videojs.options.hls = hlsOptions;
  1851. });
  1852. QUnit.test('playlist blacklisting duration is set through options', function(assert) {
  1853. const hlsOptions = videojs.options.hls;
  1854. this.player.dispose();
  1855. videojs.options.hls = {
  1856. blacklistDuration: 3 * 60
  1857. };
  1858. this.player = createPlayer();
  1859. this.player.src({
  1860. src: 'http://example.com/master.m3u8',
  1861. type: 'application/vnd.apple.mpegurl'
  1862. });
  1863. this.player.tech_.triggerReady();
  1864. openMediaSource(this.player, this.clock);
  1865. this.requests[0].respond(
  1866. 200, null,
  1867. '#EXTM3U\n' +
  1868. '#EXT-X-STREAM-INF:BANDWIDTH=1000\n' +
  1869. 'media.m3u8\n' +
  1870. '#EXT-X-STREAM-INF:BANDWIDTH=1\n' +
  1871. 'media1.m3u8\n'
  1872. );
  1873. this.requests[1].respond(404);
  1874. // media
  1875. const url = this.requests[1].url.slice(this.requests[1].url.lastIndexOf('/') + 1);
  1876. const media = this.player.tech_.hls.playlists.master.playlists[url];
  1877. assert.ok(media.excludeUntil > 0, 'original media blacklisted for some time');
  1878. assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist');
  1879. assert.equal(
  1880. this.env.log.warn.args[0],
  1881. 'Problem encountered with the current playlist. ' +
  1882. 'HLS playlist request error at URL: media.m3u8. ' +
  1883. 'Switching to another playlist.',
  1884. 'log generic error message'
  1885. );
  1886. // this takes one millisecond
  1887. this.standardXHRResponse(this.requests[2]);
  1888. this.clock.tick(2 * 60 * 1000 - 1);
  1889. assert.ok(media.excludeUntil - Date.now() > 0, 'original media still be blacklisted');
  1890. this.clock.tick(1 * 60 * 1000);
  1891. assert.equal(
  1892. media.excludeUntil,
  1893. Date.now(),
  1894. 'media\'s exclude time reach to the current time'
  1895. );
  1896. videojs.options.hls = hlsOptions;
  1897. });
  1898. QUnit.test('respects bandwidth option of 0', function(assert) {
  1899. this.player.dispose();
  1900. this.player = createPlayer({ html5: { hls: { bandwidth: 0 } } });
  1901. this.player.src({
  1902. src: 'http://example.com/media.m3u8',
  1903. type: 'application/vnd.apple.mpegurl'
  1904. });
  1905. this.clock.tick(1);
  1906. openMediaSource(this.player, this.clock);
  1907. assert.equal(this.player.tech_.hls.bandwidth, 0, 'set bandwidth to 0');
  1908. });
  1909. QUnit.test(
  1910. 'uses default bandwidth option if non-numerical value provided',
  1911. function(assert) {
  1912. this.player.dispose();
  1913. this.player = createPlayer({ html5: { hls: { bandwidth: 'garbage' } } });
  1914. this.player.src({
  1915. src: 'http://example.com/media.m3u8',
  1916. type: 'application/vnd.apple.mpegurl'
  1917. });
  1918. this.clock.tick(1);
  1919. openMediaSource(this.player, this.clock);
  1920. assert.equal(this.player.tech_.hls.bandwidth, 4194304, 'set bandwidth to default');
  1921. }
  1922. );
  1923. QUnit.test('uses default bandwidth if browser is Android', function(assert) {
  1924. this.player.dispose();
  1925. const origIsAndroid = videojs.browser.IS_ANDROID;
  1926. videojs.browser.IS_ANDROID = false;
  1927. this.player = createPlayer();
  1928. this.player.src({
  1929. src: 'http://example.com/media.m3u8',
  1930. type: 'application/vnd.apple.mpegurl'
  1931. });
  1932. openMediaSource(this.player, this.clock);
  1933. assert.equal(
  1934. this.player.tech_.hls.bandwidth,
  1935. 4194304,
  1936. 'set bandwidth to desktop default'
  1937. );
  1938. this.player.dispose();
  1939. videojs.browser.IS_ANDROID = true;
  1940. this.player = createPlayer();
  1941. this.player.src({
  1942. src: 'http://example.com/media.m3u8',
  1943. type: 'application/vnd.apple.mpegurl'
  1944. });
  1945. openMediaSource(this.player, this.clock);
  1946. assert.equal(
  1947. this.player.tech_.hls.bandwidth,
  1948. 4194304,
  1949. 'set bandwidth to mobile default'
  1950. );
  1951. videojs.browser.IS_ANDROID = origIsAndroid;
  1952. });
  1953. QUnit.test('does not break if the playlist has no segments', function(assert) {
  1954. this.player.src({
  1955. src: 'manifest/master.m3u8',
  1956. type: 'application/vnd.apple.mpegurl'
  1957. });
  1958. this.clock.tick(1);
  1959. try {
  1960. openMediaSource(this.player, this.clock);
  1961. this.requests[0].respond(
  1962. 200, null,
  1963. '#EXTM3U\n' +
  1964. '#EXT-X-PLAYLIST-TYPE:VOD\n' +
  1965. '#EXT-X-TARGETDURATION:10\n'
  1966. );
  1967. } catch (e) {
  1968. assert.ok(false, 'an error was thrown');
  1969. throw e;
  1970. }
  1971. assert.ok(true, 'no error was thrown');
  1972. assert.strictEqual(
  1973. this.requests.length,
  1974. 1,
  1975. 'no this.requestsfor non-existent segments were queued'
  1976. );
  1977. });
  1978. QUnit.test('can seek before the source buffer opens', function(assert) {
  1979. this.player.src({
  1980. src: 'media.m3u8',
  1981. type: 'application/vnd.apple.mpegurl'
  1982. });
  1983. this.clock.tick(1);
  1984. this.player.tech_.triggerReady();
  1985. this.clock.tick(1);
  1986. this.standardXHRResponse(this.requests.shift());
  1987. this.player.triggerReady();
  1988. this.player.currentTime(1);
  1989. assert.equal(this.player.currentTime(), 1, 'seeked');
  1990. });
  1991. QUnit.test('resets the switching algorithm if a request times out', function(assert) {
  1992. this.player.src({
  1993. src: 'master.m3u8',
  1994. type: 'application/vnd.apple.mpegurl'
  1995. });
  1996. this.clock.tick(1);
  1997. openMediaSource(this.player, this.clock);
  1998. this.player.tech_.hls.bandwidth = 1e20;
  1999. // master
  2000. this.standardXHRResponse(this.requests.shift());
  2001. // media.m3u8
  2002. this.standardXHRResponse(this.requests.shift());
  2003. // simulate a segment timeout
  2004. this.requests[0].timedout = true;
  2005. // segment
  2006. this.requests.shift().abort();
  2007. this.standardXHRResponse(this.requests.shift());
  2008. assert.strictEqual(
  2009. this.player.tech_.hls.playlists.media(),
  2010. this.player.tech_.hls.playlists.master.playlists[1],
  2011. 'reset to the lowest bitrate playlist'
  2012. );
  2013. // verify stats
  2014. assert.equal(this.player.tech_.hls.stats.bandwidth, 1, 'bandwidth is reset too');
  2015. });
  2016. QUnit.test('disposes the playlist loader', function(assert) {
  2017. let disposes = 0;
  2018. const player = createPlayer();
  2019. player.src({
  2020. src: 'manifest/master.m3u8',
  2021. type: 'application/vnd.apple.mpegurl'
  2022. });
  2023. this.clock.tick(1);
  2024. openMediaSource(player, this.clock);
  2025. const loaderDispose = player.tech_.hls.playlists.dispose;
  2026. player.tech_.hls.playlists.dispose = function() {
  2027. disposes++;
  2028. loaderDispose.call(player.tech_.hls.playlists);
  2029. };
  2030. player.dispose();
  2031. assert.strictEqual(disposes, 1, 'disposed playlist loader');
  2032. });
  2033. QUnit.test('remove event handlers on dispose', function(assert) {
  2034. let unscoped = 0;
  2035. const player = createPlayer();
  2036. const origPlayerOn = player.on.bind(player);
  2037. const origPlayerOff = player.off.bind(player);
  2038. player.on = function(...args) {
  2039. if (typeof args[0] !== 'object') {
  2040. unscoped++;
  2041. }
  2042. origPlayerOn(...args);
  2043. };
  2044. player.off = function(...args) {
  2045. if (typeof args[0] !== 'object') {
  2046. unscoped--;
  2047. }
  2048. origPlayerOff(...args);
  2049. };
  2050. player.src({
  2051. src: 'manifest/master.m3u8',
  2052. type: 'application/vnd.apple.mpegurl'
  2053. });
  2054. this.clock.tick(1);
  2055. openMediaSource(player, this.clock);
  2056. this.standardXHRResponse(this.requests[0]);
  2057. this.standardXHRResponse(this.requests[1]);
  2058. assert.ok(unscoped > 0, 'has unscoped handlers');
  2059. player.dispose();
  2060. assert.ok(unscoped <= 0, 'no unscoped handlers');
  2061. });
  2062. QUnit.test('the source handler supports HLS mime types', function(assert) {
  2063. assert.ok(HlsSourceHandler.canHandleSource({
  2064. type: 'aPplicatiOn/x-MPegUrl'
  2065. }), 'supports x-mpegurl');
  2066. assert.ok(HlsSourceHandler.canHandleSource({
  2067. type: 'aPplicatiOn/VnD.aPPle.MpEgUrL'
  2068. }), 'supports vnd.apple.mpegurl');
  2069. assert.ok(
  2070. HlsSourceHandler.canPlayType('aPplicatiOn/VnD.aPPle.MpEgUrL'),
  2071. 'supports vnd.apple.mpegurl'
  2072. );
  2073. assert.ok(
  2074. HlsSourceHandler.canPlayType('aPplicatiOn/x-MPegUrl'),
  2075. 'supports x-mpegurl'
  2076. );
  2077. });
  2078. QUnit.test('the source handler supports DASH mime types', function(assert) {
  2079. assert.ok(HlsSourceHandler.canHandleSource({
  2080. type: 'aPplication/dAsh+xMl'
  2081. }), 'supports application/dash+xml');
  2082. assert.ok(
  2083. HlsSourceHandler.canPlayType('aPpLicAtion/DaSh+XmL'),
  2084. 'supports application/dash+xml'
  2085. );
  2086. });
  2087. QUnit.test(
  2088. 'the source handler does not support non HLS/DASH mime types',
  2089. function(assert) {
  2090. assert.ok(!(HlsSourceHandler.canHandleSource({
  2091. type: 'video/mp4'
  2092. }) instanceof HlsHandler), 'does not support mp4');
  2093. assert.ok(!(HlsSourceHandler.canHandleSource({
  2094. type: 'video/x-flv'
  2095. }) instanceof HlsHandler), 'does not support flv');
  2096. assert.ok(
  2097. !(HlsSourceHandler.canPlayType('video/mp4')),
  2098. 'does not support mp4'
  2099. );
  2100. assert.ok(
  2101. !(HlsSourceHandler.canPlayType('video/x-flv')),
  2102. 'does not support flv'
  2103. );
  2104. }
  2105. );
  2106. QUnit.test('has no effect if native HLS is available', function(assert) {
  2107. const Html5 = videojs.getTech('Html5');
  2108. const oldHtml5CanPlaySource = Html5.canPlaySource;
  2109. Html5.canPlaySource = () => true;
  2110. Hls.supportsNativeHls = true;
  2111. const player = createPlayer();
  2112. player.src({
  2113. src: 'http://example.com/manifest/master.m3u8',
  2114. type: 'application/x-mpegURL'
  2115. });
  2116. this.clock.tick(1);
  2117. assert.ok(!player.tech_.hls, 'did not load hls tech');
  2118. player.dispose();
  2119. Html5.canPlaySource = oldHtml5CanPlaySource;
  2120. });
  2121. QUnit.test(
  2122. 'loads if native HLS is available and override is set locally',
  2123. function(assert) {
  2124. let player;
  2125. Hls.supportsNativeHls = true;
  2126. player = createPlayer({html5: {hls: {overrideNative: true}}});
  2127. this.clock.tick(1);
  2128. player.tech_.featuresNativeVideoTracks = true;
  2129. player.src({
  2130. src: 'http://example.com/manifest/master.m3u8',
  2131. type: 'application/x-mpegURL'
  2132. });
  2133. this.clock.tick(1);
  2134. assert.ok(player.tech_.hls, 'did load hls tech');
  2135. player.dispose();
  2136. player = createPlayer({html5: {hls: {overrideNative: true}}});
  2137. this.clock.tick(1);
  2138. player.tech_.featuresNativeVideoTracks = false;
  2139. player.tech_.featuresNativeAudioTracks = false;
  2140. player.src({
  2141. src: 'http://example.com/manifest/master.m3u8',
  2142. type: 'application/x-mpegURL'
  2143. });
  2144. this.clock.tick(1);
  2145. assert.ok(player.tech_.hls, 'did load hls tech');
  2146. player.dispose();
  2147. }
  2148. );
  2149. QUnit.test(
  2150. 'loads if native HLS is available and override is set globally',
  2151. function(assert) {
  2152. videojs.options.hls.overrideNative = true;
  2153. let player;
  2154. Hls.supportsNativeHls = true;
  2155. player = createPlayer();
  2156. player.tech_.featuresNativeVideoTracks = true;
  2157. player.src({
  2158. src: 'http://example.com/manifest/master.m3u8',
  2159. type: 'application/x-mpegURL'
  2160. });
  2161. this.clock.tick(1);
  2162. assert.ok(player.tech_.hls, 'did load hls tech');
  2163. player.dispose();
  2164. player = createPlayer();
  2165. player.tech_.featuresNativeVideoTracks = false;
  2166. player.tech_.featuresNativeAudioTracks = false;
  2167. player.src({
  2168. src: 'http://example.com/manifest/master.m3u8',
  2169. type: 'application/x-mpegURL'
  2170. });
  2171. this.clock.tick(1);
  2172. assert.ok(player.tech_.hls, 'did load hls tech');
  2173. player.dispose();
  2174. }
  2175. );
  2176. QUnit.test('re-emits mediachange events', function(assert) {
  2177. let mediaChanges = 0;
  2178. this.player.on('mediachange', function() {
  2179. mediaChanges++;
  2180. });
  2181. this.player.src({
  2182. src: 'http://example.com/media.m3u8',
  2183. type: 'application/vnd.apple.mpegurl'
  2184. });
  2185. this.clock.tick(1);
  2186. openMediaSource(this.player, this.clock);
  2187. this.standardXHRResponse(this.requests.shift());
  2188. this.player.tech_.hls.playlists.trigger('mediachange');
  2189. assert.strictEqual(mediaChanges, 1, 'fired mediachange');
  2190. });
  2191. QUnit.test('can be disposed before finishing initialization', function(assert) {
  2192. const readyHandlers = [];
  2193. this.player.ready = function(callback) {
  2194. readyHandlers.push(callback);
  2195. };
  2196. this.player.src({
  2197. src: 'http://example.com/media.m3u8',
  2198. type: 'application/vnd.apple.mpegurl'
  2199. });
  2200. this.clock.tick(1);
  2201. readyHandlers.shift().call(this.player);
  2202. this.player.src({
  2203. src: 'http://example.com/media.mp4',
  2204. type: 'video/mp4'
  2205. });
  2206. assert.ok(readyHandlers.length > 0, 'registered a ready handler');
  2207. try {
  2208. while (readyHandlers.length) {
  2209. readyHandlers.shift().call(this.player);
  2210. openMediaSource(this.player, this.clock);
  2211. }
  2212. assert.ok(true, 'did not throw an exception');
  2213. } catch (e) {
  2214. assert.ok(false, 'threw an exception');
  2215. }
  2216. });
  2217. QUnit.test('calling play() at the end of a video replays', function(assert) {
  2218. const done = assert.async();
  2219. let seekTime = -1;
  2220. this.player.src({
  2221. src: 'http://example.com/media.m3u8',
  2222. type: 'application/vnd.apple.mpegurl'
  2223. });
  2224. this.clock.tick(1);
  2225. openMediaSource(this.player, this.clock);
  2226. this.player.tech_.setCurrentTime = function(time) {
  2227. if (typeof time !== 'undefined') {
  2228. seekTime = time;
  2229. }
  2230. return 0;
  2231. };
  2232. this.requests.shift().respond(
  2233. 200, null,
  2234. '#EXTM3U\n' +
  2235. '#EXTINF:10,\n' +
  2236. '0.ts\n' +
  2237. '#EXT-X-ENDLIST\n'
  2238. );
  2239. this.clock.tick(1);
  2240. const segment = muxedSegment();
  2241. // copy the byte length since the segment bytes get cleared out
  2242. const segmentByteLength = segment.byteLength;
  2243. assert.ok(segmentByteLength, 'the segment has some number of bytes');
  2244. // segment 0
  2245. this.standardXHRResponse(this.requests.shift(), segment);
  2246. this.player.vhs.masterPlaylistController_.mainSegmentLoader_.one('appending', () => {
  2247. this.player.tech_.ended = function() {
  2248. return true;
  2249. };
  2250. this.player.tech_.trigger('play');
  2251. this.clock.tick(1);
  2252. assert.equal(seekTime, 0, 'seeked to the beginning');
  2253. // verify stats
  2254. assert.equal(
  2255. this.player.tech_.hls.stats.mediaBytesTransferred,
  2256. segmentByteLength,
  2257. 'transferred segment bytes'
  2258. );
  2259. assert.equal(this.player.tech_.hls.stats.mediaRequests, 1, '1 request');
  2260. done();
  2261. });
  2262. });
  2263. QUnit.test('keys are resolved relative to the master playlist', function(assert) {
  2264. this.player.src({
  2265. src: 'video/master-encrypted.m3u8',
  2266. type: 'application/vnd.apple.mpegurl'
  2267. });
  2268. this.clock.tick(1);
  2269. openMediaSource(this.player, this.clock);
  2270. this.requests.shift().respond(
  2271. 200, null,
  2272. '#EXTM3U\n' +
  2273. '#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=17\n' +
  2274. 'playlist/playlist.m3u8\n' +
  2275. '#EXT-X-ENDLIST\n'
  2276. );
  2277. this.clock.tick(1);
  2278. this.requests.shift().respond(
  2279. 200, null,
  2280. '#EXTM3U\n' +
  2281. '#EXT-X-TARGETDURATION:15\n' +
  2282. '#EXT-X-KEY:METHOD=AES-128,URI="keys/key.php"\n' +
  2283. '#EXTINF:2.833,\n' +
  2284. 'http://media.example.com/fileSequence1.ts\n' +
  2285. '#EXT-X-ENDLIST\n'
  2286. );
  2287. this.clock.tick(1);
  2288. assert.equal(this.requests.length, 2, 'requested the key');
  2289. assert.equal(
  2290. this.requests[0].url,
  2291. absoluteUrl('video/playlist/keys/key.php'),
  2292. 'resolves multiple relative paths'
  2293. );
  2294. // verify stats
  2295. assert.equal(this.player.tech_.hls.stats.bandwidth, 4194304, 'default');
  2296. });
  2297. QUnit.test('keys are resolved relative to their containing playlist', function(assert) {
  2298. this.player.src({
  2299. src: 'video/media-encrypted.m3u8',
  2300. type: 'application/vnd.apple.mpegurl'
  2301. });
  2302. this.clock.tick(1);
  2303. openMediaSource(this.player, this.clock);
  2304. this.requests.shift().respond(
  2305. 200, null,
  2306. '#EXTM3U\n' +
  2307. '#EXT-X-TARGETDURATION:15\n' +
  2308. '#EXT-X-KEY:METHOD=AES-128,URI="keys/key.php"\n' +
  2309. '#EXTINF:2.833,\n' +
  2310. 'http://media.example.com/fileSequence1.ts\n' +
  2311. '#EXT-X-ENDLIST\n'
  2312. );
  2313. this.clock.tick(1);
  2314. assert.equal(this.requests.length, 2, 'requested a key');
  2315. assert.equal(
  2316. this.requests[0].url,
  2317. absoluteUrl('video/keys/key.php'),
  2318. 'resolves multiple relative paths'
  2319. );
  2320. });
  2321. QUnit.test('keys are not requested when cached key available, cacheEncryptionKeys:true', function(assert) {
  2322. this.player.src({
  2323. src: 'video/media-encrypted.m3u8',
  2324. type: 'application/vnd.apple.mpegurl',
  2325. cacheEncryptionKeys: true
  2326. });
  2327. this.clock.tick(1);
  2328. openMediaSource(this.player, this.clock);
  2329. this.requests.shift().respond(
  2330. 200, null,
  2331. '#EXTM3U\n' +
  2332. '#EXT-X-TARGETDURATION:15\n' +
  2333. '#EXT-X-KEY:METHOD=AES-128,URI="keys/key.php",IV=0x00000000000000000000000000000000\n' +
  2334. '#EXTINF:2.833,\n' +
  2335. 'http://media.example.com/fileSequence1.ts\n' +
  2336. '#EXTINF:2.833,\n' +
  2337. 'http://media.example.com/fileSequence2.ts\n' +
  2338. '#EXT-X-ENDLIST\n'
  2339. );
  2340. this.clock.tick(1);
  2341. assert.equal(this.requests.length, 2, 'requested a key');
  2342. assert.equal(
  2343. this.requests[0].url,
  2344. absoluteUrl('video/keys/key.php'),
  2345. 'requested the key'
  2346. );
  2347. assert.equal(
  2348. this.requests[1].url,
  2349. 'http://media.example.com/fileSequence1.ts',
  2350. 'requested the segment'
  2351. );
  2352. // key response
  2353. this.standardXHRResponse(this.requests.shift(), encryptionKey());
  2354. const mpc = this.player.tech_.hls.masterPlaylistController_;
  2355. return requestAndAppendSegment({
  2356. request: this.requests.shift(),
  2357. mediaSource: mpc.mediaSource,
  2358. segmentLoader: mpc.mainSegmentLoader_,
  2359. clock: this.clock,
  2360. segment: encryptedSegment()
  2361. }).then(() => {
  2362. assert.equal(this.requests.length, 1, 'requested a segment, not a key');
  2363. assert.equal(
  2364. this.requests[0].url,
  2365. absoluteUrl('http://media.example.com/fileSequence2.ts'),
  2366. 'requested the segment only'
  2367. );
  2368. });
  2369. });
  2370. QUnit.test('keys are requested per segment, cacheEncryptionKeys:false', function(assert) {
  2371. this.player.src({
  2372. src: 'video/media-encrypted.m3u8',
  2373. type: 'application/vnd.apple.mpegurl',
  2374. cacheEncryptionKeys: false
  2375. });
  2376. this.clock.tick(1);
  2377. openMediaSource(this.player, this.clock);
  2378. this.requests.shift().respond(
  2379. 200, null,
  2380. '#EXTM3U\n' +
  2381. '#EXT-X-TARGETDURATION:15\n' +
  2382. '#EXT-X-KEY:METHOD=AES-128,URI="keys/key.php",IV=0x00000000000000000000000000000000\n' +
  2383. '#EXTINF:2.833,\n' +
  2384. 'http://media.example.com/fileSequence1.ts\n' +
  2385. '#EXTINF:2.833,\n' +
  2386. 'http://media.example.com/fileSequence2.ts\n' +
  2387. '#EXT-X-ENDLIST\n'
  2388. );
  2389. this.clock.tick(1);
  2390. assert.equal(this.requests.length, 2, 'requested a key');
  2391. assert.equal(
  2392. this.requests[0].url,
  2393. absoluteUrl('video/keys/key.php'),
  2394. 'requested the key'
  2395. );
  2396. assert.equal(
  2397. this.requests[1].url,
  2398. 'http://media.example.com/fileSequence1.ts',
  2399. 'requested the segment'
  2400. );
  2401. // key response
  2402. this.standardXHRResponse(this.requests.shift(), encryptionKey());
  2403. const mpc = this.player.tech_.hls.masterPlaylistController_;
  2404. return requestAndAppendSegment({
  2405. request: this.requests.shift(),
  2406. mediaSource: mpc.mediaSource,
  2407. segmentLoader: mpc.mainSegmentLoader_,
  2408. clock: this.clock,
  2409. segment: encryptedSegment()
  2410. }).then(() => {
  2411. assert.equal(this.requests.length, 2, 'requested a segment and a key');
  2412. assert.equal(
  2413. this.requests[0].url,
  2414. absoluteUrl('video/keys/key.php'),
  2415. 'requested the segment only'
  2416. );
  2417. assert.equal(
  2418. this.requests[1].url,
  2419. 'http://media.example.com/fileSequence2.ts',
  2420. 'requested the segment'
  2421. );
  2422. });
  2423. });
  2424. QUnit.test(
  2425. 'seeking should abort an outstanding key request and create a new one',
  2426. function(assert) {
  2427. this.player.src({
  2428. src: 'https://example.com/encrypted.m3u8',
  2429. type: 'application/vnd.apple.mpegurl'
  2430. });
  2431. this.clock.tick(1);
  2432. openMediaSource(this.player, this.clock);
  2433. this.requests.shift().respond(
  2434. 200, null,
  2435. '#EXTM3U\n' +
  2436. '#EXT-X-TARGETDURATION:15\n' +
  2437. '#EXT-X-KEY:METHOD=AES-128,URI="keys/key.php"\n' +
  2438. '#EXTINF:9,\n' +
  2439. 'http://media.example.com/fileSequence1.ts\n' +
  2440. '#EXT-X-KEY:METHOD=AES-128,URI="keys/key2.php"\n' +
  2441. '#EXTINF:9,\n' +
  2442. 'http://media.example.com/fileSequence2.ts\n' +
  2443. '#EXT-X-ENDLIST\n'
  2444. );
  2445. this.clock.tick(1);
  2446. // segment 1
  2447. this.standardXHRResponse(this.requests.pop());
  2448. this.player.currentTime(11);
  2449. this.clock.tick(2);
  2450. assert.ok(this.requests[0].aborted, 'the key XHR should be aborted');
  2451. // aborted key 1
  2452. this.requests.shift();
  2453. assert.equal(this.requests.length, 2, 'requested the new key');
  2454. assert.equal(
  2455. this.requests[0].url,
  2456. 'https://example.com/' +
  2457. this.player.tech_.hls.playlists.media().segments[1].key.uri,
  2458. 'urls should match'
  2459. );
  2460. // verify stats
  2461. assert.equal(this.player.tech_.hls.stats.mediaBytesTransferred, 1024, '1024 bytes');
  2462. assert.equal(this.player.tech_.hls.stats.mediaRequests, 1, '1 request');
  2463. }
  2464. );
  2465. QUnit.test('switching playlists with an outstanding key request aborts request and ' +
  2466. 'loads segment', function(assert) {
  2467. const media = '#EXTM3U\n' +
  2468. '#EXT-X-MEDIA-SEQUENCE:5\n' +
  2469. '#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=52"\n' +
  2470. '#EXTINF:2.833,\n' +
  2471. 'http://media.example.com/fileSequence52-A.ts\n' +
  2472. '#EXTINF:15.0,\n' +
  2473. 'http://media.example.com/fileSequence52-B.ts\n' +
  2474. '#EXT-X-ENDLIST\n';
  2475. this.player.src({
  2476. src: 'https://example.com/master.m3u8',
  2477. type: 'application/vnd.apple.mpegurl'
  2478. });
  2479. this.clock.tick(1);
  2480. openMediaSource(this.player, this.clock);
  2481. this.player.tech_.trigger('play');
  2482. this.clock.tick(1);
  2483. // master playlist
  2484. this.standardXHRResponse(this.requests.shift());
  2485. // media playlist
  2486. this.requests.shift().respond(200, null, media);
  2487. this.clock.tick(1);
  2488. // first segment of the original media playlist
  2489. this.standardXHRResponse(this.requests.pop());
  2490. assert.equal(this.requests.length, 1, 'key request only one outstanding');
  2491. const keyXhr = this.requests.shift();
  2492. assert.ok(!keyXhr.aborted, 'key request outstanding');
  2493. this.player.tech_.hls.playlists.trigger('mediachanging');
  2494. this.player.tech_.hls.playlists.trigger('mediachange');
  2495. this.clock.tick(1);
  2496. assert.ok(keyXhr.aborted, 'key request aborted');
  2497. assert.equal(this.requests.length, 2, 'loaded key and segment');
  2498. assert.equal(
  2499. this.requests[0].url,
  2500. 'https://priv.example.com/key.php?r=52',
  2501. 'requested the key'
  2502. );
  2503. assert.equal(
  2504. this.requests[1].url,
  2505. 'http://media.example.com/fileSequence52-A.ts',
  2506. 'requested the segment'
  2507. );
  2508. // verify stats
  2509. assert.equal(this.player.tech_.hls.stats.mediaBytesTransferred, 1024, '1024 bytes');
  2510. assert.equal(this.player.tech_.hls.stats.mediaRequests, 1, '1 request');
  2511. });
  2512. QUnit.test('does not download segments if preload option set to none', function(assert) {
  2513. this.player.preload('none');
  2514. this.player.src({
  2515. src: 'master.m3u8',
  2516. type: 'application/vnd.apple.mpegurl'
  2517. });
  2518. this.clock.tick(1);
  2519. openMediaSource(this.player, this.clock);
  2520. // master
  2521. this.standardXHRResponse(this.requests.shift());
  2522. // media
  2523. this.standardXHRResponse(this.requests.shift());
  2524. this.clock.tick(10 * 1000);
  2525. this.requests = this.requests.filter(function(request) {
  2526. return !(/m3u8$/).test(request.uri);
  2527. });
  2528. assert.equal(this.requests.length, 0, 'did not download any segments');
  2529. // verify stats
  2530. assert.equal(this.player.tech_.hls.stats.bandwidth, 4194304, 'default');
  2531. });
  2532. // workaround https://bugzilla.mozilla.org/show_bug.cgi?id=548397
  2533. QUnit.test(
  2534. 'selectPlaylist does not fail if getComputedStyle returns null',
  2535. function(assert) {
  2536. const oldGetComputedStyle = window.getComputedStyle;
  2537. window.getComputedStyle = function() {
  2538. return null;
  2539. };
  2540. this.player.src({
  2541. src: 'master.m3u8',
  2542. type: 'application/vnd.apple.mpegurl'
  2543. });
  2544. this.clock.tick(1);
  2545. openMediaSource(this.player, this.clock);
  2546. // master
  2547. this.standardXHRResponse(this.requests.shift());
  2548. // media
  2549. this.standardXHRResponse(this.requests.shift());
  2550. this.player.tech_.hls.selectPlaylist();
  2551. assert.ok(true, 'should not throw');
  2552. window.getComputedStyle = oldGetComputedStyle;
  2553. // verify stats
  2554. assert.equal(this.player.tech_.hls.stats.bandwidth, 4194304, 'default');
  2555. }
  2556. );
  2557. QUnit.test('resolves relative key URLs against the playlist', function(assert) {
  2558. this.player.src({
  2559. src: 'https://example.com/media.m3u8',
  2560. type: 'application/vnd.apple.mpegurl'
  2561. });
  2562. this.clock.tick(1);
  2563. openMediaSource(this.player, this.clock);
  2564. this.requests.shift()
  2565. .respond(
  2566. 200, null,
  2567. '#EXTM3U\n' +
  2568. '#EXT-X-MEDIA-SEQUENCE:5\n' +
  2569. '#EXT-X-KEY:METHOD=AES-128,URI="key.php?r=52"\n' +
  2570. '#EXTINF:2.833,\n' +
  2571. 'http://media.example.com/fileSequence52-A.ts\n' +
  2572. '#EXT-X-ENDLIST\n'
  2573. );
  2574. this.clock.tick(1);
  2575. assert.equal(
  2576. this.requests[0].url,
  2577. 'https://example.com/key.php?r=52',
  2578. 'resolves the key URL'
  2579. );
  2580. });
  2581. QUnit.test(
  2582. 'adds 1 default audio track if we have not parsed any and the playlist is loaded',
  2583. function(assert) {
  2584. this.player.src({
  2585. src: 'manifest/master.m3u8',
  2586. type: 'application/vnd.apple.mpegurl'
  2587. });
  2588. this.clock.tick(1);
  2589. assert.equal(this.player.audioTracks().length, 0, 'zero audio tracks at load time');
  2590. openMediaSource(this.player, this.clock);
  2591. // master
  2592. this.standardXHRResponse(this.requests.shift());
  2593. // media
  2594. this.standardXHRResponse(this.requests.shift());
  2595. assert.equal(this.player.audioTracks().length, 1, 'one audio track after load');
  2596. assert.equal(this.player.audioTracks()[0].label, 'default', 'set the label');
  2597. }
  2598. );
  2599. QUnit.test('adds audio tracks if we have parsed some from a playlist', function(assert) {
  2600. this.player.src({
  2601. src: 'manifest/multipleAudioGroups.m3u8',
  2602. type: 'application/vnd.apple.mpegurl'
  2603. });
  2604. this.clock.tick(1);
  2605. assert.equal(this.player.audioTracks().length, 0, 'zero audio tracks at load time');
  2606. openMediaSource(this.player, this.clock);
  2607. // master
  2608. this.standardXHRResponse(this.requests.shift());
  2609. // media
  2610. this.standardXHRResponse(this.requests.shift());
  2611. const vjsAudioTracks = this.player.audioTracks();
  2612. assert.equal(vjsAudioTracks.length, 3, '3 active vjs tracks');
  2613. assert.equal(vjsAudioTracks[0].enabled, true, 'default track is enabled');
  2614. vjsAudioTracks[1].enabled = true;
  2615. assert.equal(vjsAudioTracks[1].enabled, true, 'new track is enabled on vjs');
  2616. assert.equal(vjsAudioTracks[0].enabled, false, 'main track is disabled');
  2617. });
  2618. QUnit.test('cleans up the buffer when loading live segments', function(assert) {
  2619. const seekable = videojs.createTimeRanges([[0, 70]]);
  2620. this.player.src({
  2621. src: 'liveStart30sBefore.m3u8',
  2622. type: 'application/vnd.apple.mpegurl'
  2623. });
  2624. this.clock.tick(1);
  2625. openMediaSource(this.player, this.clock);
  2626. this.player.tech_.hls.masterPlaylistController_.seekable = function() {
  2627. return seekable;
  2628. };
  2629. this.player.tech_.hls.bandwidth = 20e10;
  2630. this.player.tech_.readyState = () => 4;
  2631. this.player.tech_.triggerReady();
  2632. // media
  2633. this.standardXHRResponse(this.requests[0]);
  2634. this.player.tech_.hls.playlists.trigger('loadedmetadata');
  2635. this.player.tech_.trigger('canplay');
  2636. this.player.tech_.paused = function() {
  2637. return false;
  2638. };
  2639. this.player.tech_.trigger('play');
  2640. this.clock.tick(1);
  2641. const mpc = this.player.tech_.hls.masterPlaylistController_;
  2642. const audioRemoves = [];
  2643. const videoRemoves = [];
  2644. // request first playable segment
  2645. return requestAndAppendSegment({
  2646. request: this.requests[1],
  2647. mediaSource: mpc.mediaSource,
  2648. segmentLoader: mpc.mainSegmentLoader_,
  2649. clock: this.clock
  2650. }).then(() => {
  2651. const audioBuffer = mpc.sourceUpdater_.audioBuffer;
  2652. const videoBuffer = mpc.sourceUpdater_.videoBuffer;
  2653. const origAudioRemove = audioBuffer.remove.bind(audioBuffer);
  2654. const origVideoRemove = videoBuffer.remove.bind(videoBuffer);
  2655. audioBuffer.remove = (start, end) => {
  2656. audioRemoves.push({start, end});
  2657. origAudioRemove();
  2658. };
  2659. videoBuffer.remove = (start, end) => {
  2660. videoRemoves.push({start, end});
  2661. origVideoRemove();
  2662. };
  2663. // since source buffers are mocked, must fake that there's buffered data, or else we
  2664. // don't bother processing removes
  2665. audioBuffer.buffered = videojs.createTimeRanges([[10, 20]]);
  2666. videoBuffer.buffered = videojs.createTimeRanges([[15, 25]]);
  2667. // request second segment, and give enough time for the source buffer to process removes
  2668. return requestAndAppendSegment({
  2669. request: this.requests[2],
  2670. mediaSource: mpc.mediaSource,
  2671. segmentLoader: mpc.mainSegmentLoader_,
  2672. clock: this.clock
  2673. });
  2674. }).then(() => {
  2675. assert.equal(audioRemoves.length, 1, 'one audio remove');
  2676. assert.equal(videoRemoves.length, 1, 'one video remove');
  2677. // segment-loader removes at currentTime - 30
  2678. assert.deepEqual(
  2679. audioRemoves[0],
  2680. { start: 0, end: 40 },
  2681. 'removed from audio buffer with right range'
  2682. );
  2683. assert.deepEqual(
  2684. videoRemoves[0],
  2685. { start: 0, end: 40 },
  2686. 'removed from video buffer with right range'
  2687. );
  2688. });
  2689. });
  2690. QUnit.test('cleans up the buffer based on currentTime when loading a live segment ' +
  2691. 'if seekable start is after currentTime', function(assert) {
  2692. let seekable = videojs.createTimeRanges([[0, 80]]);
  2693. this.player.src({
  2694. src: 'liveStart30sBefore.m3u8',
  2695. type: 'application/vnd.apple.mpegurl'
  2696. });
  2697. openMediaSource(this.player, this.clock);
  2698. this.player.tech_.hls.masterPlaylistController_.seekable = function() {
  2699. return seekable;
  2700. };
  2701. this.player.tech_.readyState = () => 4;
  2702. this.player.tech_.hls.bandwidth = 20e10;
  2703. this.player.tech_.triggerReady();
  2704. // media
  2705. this.standardXHRResponse(this.requests.shift());
  2706. this.player.tech_.hls.playlists.trigger('loadedmetadata');
  2707. this.player.tech_.trigger('canplay');
  2708. this.player.tech_.paused = function() {
  2709. return false;
  2710. };
  2711. this.player.tech_.trigger('play');
  2712. this.clock.tick(1);
  2713. const mpc = this.player.tech_.hls.masterPlaylistController_;
  2714. const audioRemoves = [];
  2715. const videoRemoves = [];
  2716. // request first playable segment
  2717. return requestAndAppendSegment({
  2718. request: this.requests.shift(),
  2719. mediaSource: mpc.mediaSource,
  2720. segmentLoader: mpc.mainSegmentLoader_,
  2721. clock: this.clock
  2722. }).then(() => {
  2723. // Change seekable so that it starts *after* the currentTime which was set
  2724. // based on the previous seekable range (the end of 80)
  2725. seekable = videojs.createTimeRanges([[100, 120]]);
  2726. this.clock.tick(1);
  2727. const audioBuffer = mpc.sourceUpdater_.audioBuffer;
  2728. const videoBuffer = mpc.sourceUpdater_.videoBuffer;
  2729. const origAudioRemove = audioBuffer.remove.bind(audioBuffer);
  2730. const origVideoRemove = videoBuffer.remove.bind(videoBuffer);
  2731. audioBuffer.remove = (start, end) => {
  2732. audioRemoves.push({start, end});
  2733. origAudioRemove();
  2734. };
  2735. videoBuffer.remove = (start, end) => {
  2736. videoRemoves.push({start, end});
  2737. origVideoRemove();
  2738. };
  2739. // since source buffers are mocked, must fake that there's buffered data, or else we
  2740. // don't bother processing removes
  2741. audioBuffer.buffered = videojs.createTimeRanges([[10, 20]]);
  2742. videoBuffer.buffered = videojs.createTimeRanges([[15, 25]]);
  2743. // prevent trying to correct live time
  2744. disposePlaybackWatcher(this.player);
  2745. // request second segment, and give enough time for the source buffer to process removes
  2746. return requestAndAppendSegment({
  2747. request: this.requests.shift(),
  2748. mediaSource: mpc.mediaSource,
  2749. segmentLoader: mpc.mainSegmentLoader_,
  2750. clock: this.clock
  2751. });
  2752. }).then(() => {
  2753. assert.equal(audioRemoves.length, 1, 'one audio remove');
  2754. assert.equal(videoRemoves.length, 1, 'one video remove');
  2755. // segment-loader removes at currentTime - 30
  2756. assert.deepEqual(
  2757. audioRemoves[0],
  2758. { start: 0, end: 80 - 30 },
  2759. 'removed from audio buffer with right range'
  2760. );
  2761. assert.deepEqual(
  2762. videoRemoves[0],
  2763. { start: 0, end: 80 - 30 },
  2764. 'removed from video buffer with right range'
  2765. );
  2766. });
  2767. });
  2768. QUnit.test('cleans up the buffer when loading VOD segments', function(assert) {
  2769. this.player.src({
  2770. src: 'manifest/master.m3u8',
  2771. type: 'application/vnd.apple.mpegurl'
  2772. });
  2773. this.clock.tick(1);
  2774. openMediaSource(this.player, this.clock);
  2775. this.player.width(640);
  2776. this.player.height(360);
  2777. this.player.tech_.hls.bandwidth = 20e10;
  2778. // master
  2779. this.standardXHRResponse(this.requests[0]);
  2780. // media
  2781. this.standardXHRResponse(this.requests[1]);
  2782. const mpc = this.player.tech_.hls.masterPlaylistController_;
  2783. const audioRemoves = [];
  2784. const videoRemoves = [];
  2785. // first segment request will set up all of the source buffers we need
  2786. return requestAndAppendSegment({
  2787. request: this.requests[2],
  2788. mediaSource: mpc.mediaSource,
  2789. segmentLoader: mpc.mainSegmentLoader_,
  2790. clock: this.clock,
  2791. tickClock: false
  2792. }).then(() => {
  2793. // the seek will have removed everything to the duration of the video, so we want to
  2794. // only start tracking removes after the seek, once the next segment request is made
  2795. this.player.currentTime(120);
  2796. const audioBuffer = mpc.sourceUpdater_.audioBuffer;
  2797. const videoBuffer = mpc.sourceUpdater_.videoBuffer;
  2798. const origAudioRemove = audioBuffer.remove.bind(audioBuffer);
  2799. const origVideoRemove = videoBuffer.remove.bind(videoBuffer);
  2800. audioBuffer.remove = (start, end) => {
  2801. audioRemoves.push({start, end});
  2802. origAudioRemove();
  2803. };
  2804. videoBuffer.remove = (start, end) => {
  2805. videoRemoves.push({start, end});
  2806. origVideoRemove();
  2807. };
  2808. // since source buffers are mocked, must fake that there's buffered data, or else we
  2809. // don't bother processing removes
  2810. audioBuffer.buffered = videojs.createTimeRanges([[0, 10]]);
  2811. videoBuffer.buffered = videojs.createTimeRanges([[1, 11]]);
  2812. // This requires 2 clock ticks because after updateend monitorBuffer_ is called
  2813. // to setup fillBuffer on the next tick, but the seek also causes monitorBuffer_ to be
  2814. // called, which cancels the previously set timeout and sets a new one for the following
  2815. // tick.
  2816. this.clock.tick(2);
  2817. // request second segment, and give enough time for the source buffer to process removes
  2818. return requestAndAppendSegment({
  2819. request: this.requests[3],
  2820. mediaSource: mpc.mediaSource,
  2821. segmentLoader: mpc.mainSegmentLoader_,
  2822. clock: this.clock
  2823. });
  2824. }).then(() => {
  2825. assert.equal(audioRemoves.length, 1, 'one audio remove');
  2826. assert.equal(videoRemoves.length, 1, 'one video remove');
  2827. // segment-loader removes at currentTime - 30
  2828. assert.deepEqual(
  2829. audioRemoves[0],
  2830. { start: 0, end: 120 - 30 },
  2831. 'removed from audio buffer with right range'
  2832. );
  2833. assert.deepEqual(
  2834. videoRemoves[0],
  2835. { start: 0, end: 120 - 30 },
  2836. 'removed from video buffer with right range'
  2837. );
  2838. });
  2839. });
  2840. QUnit.test('when mediaGroup changes enabled track should not change', function(assert) {
  2841. let hlsAudioChangeEvents = 0;
  2842. this.player.src({
  2843. src: 'manifest/multipleAudioGroups.m3u8',
  2844. type: 'application/vnd.apple.mpegurl'
  2845. });
  2846. this.clock.tick(1);
  2847. openMediaSource(this.player, this.clock);
  2848. this.player.tech_.on('usage', (event) => {
  2849. if (event.name === 'hls-audio-change') {
  2850. hlsAudioChangeEvents++;
  2851. }
  2852. });
  2853. // master
  2854. this.standardXHRResponse(this.requests.shift());
  2855. // video media
  2856. this.standardXHRResponse(this.requests.shift());
  2857. const hls = this.player.tech_.hls;
  2858. const mpc = hls.masterPlaylistController_;
  2859. let audioTracks = this.player.audioTracks();
  2860. assert.equal(hlsAudioChangeEvents, 0, 'no hls-audio-change event was fired');
  2861. assert.equal(audioTracks.length, 3, 'three audio tracks after load');
  2862. assert.equal(audioTracks[0].enabled, true, 'track one enabled after load');
  2863. let oldMediaGroup = hls.playlists.media().attributes.AUDIO;
  2864. // clear out any outstanding requests
  2865. this.requests.length = 0;
  2866. // force mpc to select a playlist from a new media group
  2867. mpc.masterPlaylistLoader_.media(mpc.master().playlists[0]);
  2868. this.clock.tick(1);
  2869. // video media
  2870. this.standardXHRResponse(this.requests.shift());
  2871. assert.notEqual(
  2872. oldMediaGroup,
  2873. hls.playlists.media().attributes.AUDIO,
  2874. 'selected a new playlist'
  2875. );
  2876. audioTracks = this.player.audioTracks();
  2877. const activeGroup = mpc.mediaTypes_.AUDIO.activeGroup(audioTracks[0]);
  2878. assert.equal(audioTracks.length, 3, 'three audio tracks after changing mediaGroup');
  2879. assert.ok(activeGroup.default, 'track one should be the default');
  2880. assert.ok(audioTracks[0].enabled, 'enabled the default track');
  2881. assert.notOk(audioTracks[1].enabled, 'disabled track two');
  2882. assert.notOk(audioTracks[2].enabled, 'disabled track three');
  2883. audioTracks[1].enabled = true;
  2884. assert.notOk(audioTracks[0].enabled, 'disabled track one');
  2885. assert.ok(audioTracks[1].enabled, 'enabled track two');
  2886. assert.notOk(audioTracks[2].enabled, 'disabled track three');
  2887. oldMediaGroup = hls.playlists.media().attributes.AUDIO;
  2888. // clear out any outstanding requests
  2889. this.requests.length = 0;
  2890. // swap back to the old media group
  2891. // this playlist is already loaded so no new requests are made
  2892. mpc.masterPlaylistLoader_.media(mpc.master().playlists[3]);
  2893. this.clock.tick(1);
  2894. assert.notEqual(
  2895. oldMediaGroup,
  2896. hls.playlists.media().attributes.AUDIO,
  2897. 'selected a new playlist'
  2898. );
  2899. audioTracks = this.player.audioTracks();
  2900. assert.equal(hlsAudioChangeEvents, 1, 'an hls-audio-change event was fired');
  2901. assert.equal(audioTracks.length, 3, 'three audio tracks after reverting mediaGroup');
  2902. assert.notOk(audioTracks[0].enabled, 'the default track is still disabled');
  2903. assert.ok(audioTracks[1].enabled, 'track two is still enabled');
  2904. assert.notOk(audioTracks[2].enabled, 'track three is still disabled');
  2905. });
  2906. QUnit.test(
  2907. 'Allows specifying the beforeRequest function on the player',
  2908. function(assert) {
  2909. let beforeRequestCalled = false;
  2910. this.player.src({
  2911. src: 'master.m3u8',
  2912. type: 'application/vnd.apple.mpegurl'
  2913. });
  2914. this.clock.tick(1);
  2915. openMediaSource(this.player, this.clock);
  2916. this.player.tech_.hls.xhr.beforeRequest = function() {
  2917. beforeRequestCalled = true;
  2918. };
  2919. // master
  2920. this.standardXHRResponse(this.requests.shift());
  2921. // media
  2922. this.standardXHRResponse(this.requests.shift());
  2923. assert.ok(beforeRequestCalled, 'beforeRequest was called');
  2924. // verify stats
  2925. assert.equal(this.player.tech_.hls.stats.bandwidth, 4194304, 'default');
  2926. }
  2927. );
  2928. QUnit.test('Allows specifying the beforeRequest function globally', function(assert) {
  2929. let beforeRequestCalled = false;
  2930. videojs.Hls.xhr.beforeRequest = function() {
  2931. beforeRequestCalled = true;
  2932. };
  2933. this.player.src({
  2934. src: 'master.m3u8',
  2935. type: 'application/vnd.apple.mpegurl'
  2936. });
  2937. this.clock.tick(1);
  2938. openMediaSource(this.player, this.clock);
  2939. // master
  2940. this.standardXHRResponse(this.requests.shift());
  2941. assert.ok(beforeRequestCalled, 'beforeRequest was called');
  2942. delete videojs.Hls.xhr.beforeRequest;
  2943. // verify stats
  2944. assert.equal(this.player.tech_.hls.stats.bandwidth, 4194304, 'default');
  2945. });
  2946. QUnit.test('Allows overriding the global beforeRequest function', function(assert) {
  2947. let beforeGlobalRequestCalled = 0;
  2948. let beforeLocalRequestCalled = 0;
  2949. videojs.Hls.xhr.beforeRequest = function() {
  2950. beforeGlobalRequestCalled++;
  2951. };
  2952. this.player.src({
  2953. src: 'master.m3u8',
  2954. type: 'application/vnd.apple.mpegurl'
  2955. });
  2956. this.clock.tick(1);
  2957. openMediaSource(this.player, this.clock);
  2958. this.player.tech_.hls.xhr.beforeRequest = function() {
  2959. beforeLocalRequestCalled++;
  2960. };
  2961. // master
  2962. this.standardXHRResponse(this.requests.shift());
  2963. // media
  2964. this.standardXHRResponse(this.requests.shift());
  2965. // ts
  2966. this.standardXHRResponse(this.requests.shift());
  2967. assert.equal(beforeLocalRequestCalled, 2, 'local beforeRequest was called twice ' +
  2968. 'for the media playlist and media');
  2969. assert.equal(beforeGlobalRequestCalled, 1, 'global beforeRequest was called once ' +
  2970. 'for the master playlist');
  2971. delete videojs.Hls.xhr.beforeRequest;
  2972. });
  2973. QUnit.test(
  2974. 'passes useCueTags hls option to master playlist controller',
  2975. function(assert) {
  2976. this.player.src({
  2977. src: 'master.m3u8',
  2978. type: 'application/vnd.apple.mpegurl'
  2979. });
  2980. this.clock.tick(1);
  2981. assert.ok(
  2982. !this.player.tech_.hls.masterPlaylistController_.useCueTags_,
  2983. 'useCueTags is falsy by default'
  2984. );
  2985. const origHlsOptions = videojs.options.hls;
  2986. videojs.options.hls = {
  2987. useCueTags: true
  2988. };
  2989. this.player.dispose();
  2990. this.player = createPlayer();
  2991. this.player.src({
  2992. src: 'http://example.com/media.m3u8',
  2993. type: 'application/vnd.apple.mpegurl'
  2994. });
  2995. this.clock.tick(1);
  2996. assert.ok(
  2997. this.player.tech_.hls.masterPlaylistController_.useCueTags_,
  2998. 'useCueTags passed to master playlist controller'
  2999. );
  3000. videojs.options.hls = origHlsOptions;
  3001. }
  3002. );
  3003. // TODO: This test fails intermittently. Turn on when fixed to always pass.
  3004. QUnit.skip('populates quality levels list when available', function(assert) {
  3005. this.player.src({
  3006. src: 'manifest/master.m3u8',
  3007. type: 'application/vnd.apple.mpegurl'
  3008. });
  3009. this.clock.tick(1);
  3010. openMediaSource(this.player, this.clock);
  3011. assert.ok(this.player.tech_.hls.qualityLevels_, 'added quality levels');
  3012. const qualityLevels = this.player.qualityLevels();
  3013. let addCount = 0;
  3014. let changeCount = 0;
  3015. qualityLevels.on('addqualitylevel', () => {
  3016. addCount++;
  3017. });
  3018. qualityLevels.on('change', () => {
  3019. changeCount++;
  3020. });
  3021. // master
  3022. this.standardXHRResponse(this.requests.shift());
  3023. // media
  3024. this.standardXHRResponse(this.requests.shift());
  3025. assert.equal(addCount, 4, 'four levels added from master');
  3026. assert.equal(changeCount, 1, 'selected initial quality level');
  3027. this.player.dispose();
  3028. this.player = createPlayer({}, {
  3029. src: 'http://example.com/media.m3u8',
  3030. type: 'application/vnd.apple.mpegurl'
  3031. }, this.clock);
  3032. openMediaSource(this.player, this.clock);
  3033. assert.ok(
  3034. this.player.tech_.hls.qualityLevels_,
  3035. 'added quality levels from video with source'
  3036. );
  3037. });
  3038. QUnit.test('configures eme if present on selectedinitialmedia', function(assert) {
  3039. this.player.eme = {
  3040. options: {
  3041. previousSetting: 1
  3042. }
  3043. };
  3044. this.player.src({
  3045. src: 'manifest/master.mpd',
  3046. type: 'application/dash+xml',
  3047. keySystems: {
  3048. keySystem1: {
  3049. url: 'url1'
  3050. }
  3051. }
  3052. });
  3053. this.clock.tick(1);
  3054. this.player.tech_.hls.playlists = {
  3055. media: () => {
  3056. return {
  3057. attributes: {
  3058. CODECS: 'video-codec'
  3059. },
  3060. contentProtection: {
  3061. keySystem1: {
  3062. pssh: 'test'
  3063. }
  3064. }
  3065. };
  3066. },
  3067. // mocked for renditions mixin
  3068. master: {
  3069. playlists: []
  3070. }
  3071. };
  3072. this.player.tech_.hls.masterPlaylistController_.mediaTypes_ = {
  3073. SUBTITLES: {},
  3074. AUDIO: {
  3075. activePlaylistLoader: {
  3076. media: () => {
  3077. return {
  3078. attributes: {
  3079. CODECS: 'audio-codec'
  3080. }
  3081. };
  3082. }
  3083. }
  3084. }
  3085. };
  3086. this.player.tech_.hls.masterPlaylistController_.trigger('selectedinitialmedia');
  3087. assert.deepEqual(this.player.eme.options, {
  3088. previousSetting: 1
  3089. }, 'did not modify plugin options');
  3090. assert.deepEqual(this.player.currentSource(), {
  3091. src: 'manifest/master.mpd',
  3092. type: 'application/dash+xml',
  3093. keySystems: {
  3094. keySystem1: {
  3095. url: 'url1',
  3096. audioContentType: 'audio/mp4; codecs="audio-codec"',
  3097. videoContentType: 'video/mp4; codecs="video-codec"',
  3098. pssh: 'test'
  3099. }
  3100. }
  3101. }, 'set source eme options');
  3102. });
  3103. QUnit.test('integration: configures eme if present on selectedinitialmedia', function(assert) {
  3104. assert.timeout(3000);
  3105. const done = assert.async();
  3106. this.player.eme = {
  3107. options: {
  3108. previousSetting: 1
  3109. }
  3110. };
  3111. this.player.src({
  3112. src: 'dash.mpd',
  3113. type: 'application/dash+xml',
  3114. keySystems: {
  3115. keySystem1: {
  3116. url: 'url1'
  3117. }
  3118. }
  3119. });
  3120. this.clock.tick(1);
  3121. this.player.tech_.hls.masterPlaylistController_.on('selectedinitialmedia', () => {
  3122. assert.deepEqual(this.player.eme.options, {
  3123. previousSetting: 1
  3124. }, 'did not modify plugin options');
  3125. assert.deepEqual(this.player.currentSource(), {
  3126. src: 'dash.mpd',
  3127. type: 'application/dash+xml',
  3128. keySystems: {
  3129. keySystem1: {
  3130. url: 'url1',
  3131. audioContentType: 'audio/mp4; codecs="mp4a.40.2"',
  3132. videoContentType: 'video/mp4; codecs="avc1.420015"'
  3133. }
  3134. }
  3135. }, 'set source eme options');
  3136. done();
  3137. });
  3138. this.standardXHRResponse(this.requests[0]);
  3139. // this allows the audio playlist loader to load
  3140. this.clock.tick(1);
  3141. });
  3142. QUnit.test(
  3143. 'does not set source keySystems if keySystems not provided by source',
  3144. function(assert) {
  3145. this.player.src({
  3146. src: 'manifest/master.mpd',
  3147. type: 'application/dash+xml'
  3148. });
  3149. this.clock.tick(1);
  3150. this.player.tech_.hls.playlists = {
  3151. media: () => {
  3152. return {
  3153. attributes: {
  3154. CODECS: 'video-codec'
  3155. },
  3156. contentProtection: {
  3157. keySystem1: {
  3158. pssh: 'test'
  3159. }
  3160. }
  3161. };
  3162. },
  3163. // mocked for renditions mixin
  3164. master: {
  3165. playlists: []
  3166. }
  3167. };
  3168. this.player.tech_.hls.masterPlaylistController_.mediaTypes_ = {
  3169. SUBTITLES: {},
  3170. AUDIO: {
  3171. activePlaylistLoader: {
  3172. media: () => {
  3173. return {
  3174. attributes: {
  3175. CODECS: 'audio-codec'
  3176. }
  3177. };
  3178. }
  3179. }
  3180. }
  3181. };
  3182. this.player.tech_.hls.masterPlaylistController_.trigger('selectedinitialmedia');
  3183. assert.deepEqual(this.player.currentSource(), {
  3184. src: 'manifest/master.mpd',
  3185. type: 'application/dash+xml'
  3186. }, 'does not set source eme options');
  3187. }
  3188. );
  3189. QUnit[testOrSkip](
  3190. 'stores bandwidth and throughput in localStorage when global option is true',
  3191. function(assert) {
  3192. videojs.options.hls = {
  3193. useBandwidthFromLocalStorage: true
  3194. };
  3195. this.player.src({
  3196. src: 'manifest/master.m3u8',
  3197. type: 'application/vnd.apple.mpegurl'
  3198. });
  3199. openMediaSource(this.player, this.clock);
  3200. // master
  3201. this.standardXHRResponse(this.requests.shift());
  3202. // media
  3203. this.standardXHRResponse(this.requests.shift());
  3204. assert.notOk(window.localStorage.getItem(LOCAL_STORAGE_KEY), 'nothing in local storage');
  3205. this.player.tech_.hls.masterPlaylistController_.mainSegmentLoader_.bandwidth = 11;
  3206. this.player.tech_.hls.masterPlaylistController_.mainSegmentLoader_.throughput.rate = 22;
  3207. this.player.tech_.trigger('bandwidthupdate');
  3208. const storedObject = JSON.parse(window.localStorage.getItem(LOCAL_STORAGE_KEY));
  3209. assert.equal(parseInt(storedObject.bandwidth, 10), 11, 'set bandwidth');
  3210. assert.equal(parseInt(storedObject.throughput, 10), 22, 'set throughput');
  3211. }
  3212. );
  3213. QUnit[testOrSkip](
  3214. 'stores bandwidth and throughput in localStorage when player option is true',
  3215. function(assert) {
  3216. this.player.dispose();
  3217. this.player = createPlayer({
  3218. html5: {
  3219. hls: {
  3220. useBandwidthFromLocalStorage: true
  3221. }
  3222. }
  3223. });
  3224. this.player.src({
  3225. src: 'manifest/master.m3u8',
  3226. type: 'application/vnd.apple.mpegurl'
  3227. });
  3228. openMediaSource(this.player, this.clock);
  3229. // master
  3230. this.standardXHRResponse(this.requests.shift());
  3231. // media
  3232. this.standardXHRResponse(this.requests.shift());
  3233. assert.notOk(window.localStorage.getItem(LOCAL_STORAGE_KEY), 'nothing in local storage');
  3234. this.player.tech_.hls.masterPlaylistController_.mainSegmentLoader_.bandwidth = 11;
  3235. this.player.tech_.hls.masterPlaylistController_.mainSegmentLoader_.throughput.rate = 22;
  3236. this.player.tech_.trigger('bandwidthupdate');
  3237. const storedObject = JSON.parse(window.localStorage.getItem(LOCAL_STORAGE_KEY));
  3238. assert.equal(parseInt(storedObject.bandwidth, 10), 11, 'set bandwidth');
  3239. assert.equal(parseInt(storedObject.throughput, 10), 22, 'set throughput');
  3240. }
  3241. );
  3242. QUnit[testOrSkip](
  3243. 'stores bandwidth and throughput in localStorage when source option is true',
  3244. function(assert) {
  3245. this.player.dispose();
  3246. this.player = createPlayer();
  3247. this.player.src({
  3248. src: 'manifest/master.m3u8',
  3249. type: 'application/vnd.apple.mpegurl',
  3250. useBandwidthFromLocalStorage: true
  3251. });
  3252. openMediaSource(this.player, this.clock);
  3253. // master
  3254. this.standardXHRResponse(this.requests.shift());
  3255. // media
  3256. this.standardXHRResponse(this.requests.shift());
  3257. assert.notOk(window.localStorage.getItem(LOCAL_STORAGE_KEY), 'nothing in local storage');
  3258. this.player.tech_.hls.masterPlaylistController_.mainSegmentLoader_.bandwidth = 11;
  3259. this.player.tech_.hls.masterPlaylistController_.mainSegmentLoader_.throughput.rate = 22;
  3260. this.player.tech_.trigger('bandwidthupdate');
  3261. const storedObject = JSON.parse(window.localStorage.getItem(LOCAL_STORAGE_KEY));
  3262. assert.equal(parseInt(storedObject.bandwidth, 10), 11, 'set bandwidth');
  3263. assert.equal(parseInt(storedObject.throughput, 10), 22, 'set throughput');
  3264. }
  3265. );
  3266. QUnit[testOrSkip](
  3267. 'source localStorage option takes priority over player option',
  3268. function(assert) {
  3269. this.player.dispose();
  3270. this.player = createPlayer({
  3271. html5: {
  3272. hls: {
  3273. useBandwidthFromLocalStorage: false
  3274. }
  3275. }
  3276. });
  3277. this.player.src({
  3278. src: 'manifest/master.m3u8',
  3279. type: 'application/vnd.apple.mpegurl',
  3280. useBandwidthFromLocalStorage: true
  3281. });
  3282. openMediaSource(this.player, this.clock);
  3283. // master
  3284. this.standardXHRResponse(this.requests.shift());
  3285. // media
  3286. this.standardXHRResponse(this.requests.shift());
  3287. assert.notOk(window.localStorage.getItem(LOCAL_STORAGE_KEY), 'nothing in local storage');
  3288. this.player.tech_.hls.masterPlaylistController_.mainSegmentLoader_.bandwidth = 11;
  3289. this.player.tech_.hls.masterPlaylistController_.mainSegmentLoader_.throughput.rate = 22;
  3290. this.player.tech_.trigger('bandwidthupdate');
  3291. const storedObject = JSON.parse(window.localStorage.getItem(LOCAL_STORAGE_KEY));
  3292. assert.equal(parseInt(storedObject.bandwidth, 10), 11, 'set bandwidth');
  3293. assert.equal(parseInt(storedObject.throughput, 10), 22, 'set throughput');
  3294. }
  3295. );
  3296. QUnit[testOrSkip](
  3297. 'does not store bandwidth and throughput in localStorage by default',
  3298. function(assert) {
  3299. this.player = createPlayer();
  3300. this.player.src({
  3301. src: 'manifest/master.m3u8',
  3302. type: 'application/vnd.apple.mpegurl'
  3303. });
  3304. openMediaSource(this.player, this.clock);
  3305. // master
  3306. this.standardXHRResponse(this.requests.shift());
  3307. // media
  3308. this.standardXHRResponse(this.requests.shift());
  3309. assert.notOk(window.localStorage.getItem(LOCAL_STORAGE_KEY), 'nothing in local storage');
  3310. this.player.tech_.hls.masterPlaylistController_.mainSegmentLoader_.bandwidth = 11;
  3311. this.player.tech_.hls.masterPlaylistController_.mainSegmentLoader_.throughput.rate = 22;
  3312. this.player.tech_.trigger('bandwidthupdate');
  3313. assert.notOk(window.localStorage.getItem(LOCAL_STORAGE_KEY), 'nothing in local storage');
  3314. }
  3315. );
  3316. QUnit[testOrSkip]('retrieves bandwidth and throughput from localStorage', function(assert) {
  3317. window.localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify({
  3318. bandwidth: 33,
  3319. throughput: 44
  3320. }));
  3321. let bandwidthUsageEvents = 0;
  3322. let throughputUsageEvents = 0;
  3323. const usageListener = (event) => {
  3324. if (event.name === 'hls-bandwidth-from-local-storage') {
  3325. bandwidthUsageEvents++;
  3326. }
  3327. if (event.name === 'hls-throughput-from-local-storage') {
  3328. throughputUsageEvents++;
  3329. }
  3330. };
  3331. // values must be stored before player is created, otherwise defaults are provided
  3332. this.player = createPlayer();
  3333. this.player.tech_.on('usage', usageListener);
  3334. this.player.src({
  3335. src: 'manifest/master.m3u8',
  3336. type: 'application/vnd.apple.mpegurl'
  3337. });
  3338. openMediaSource(this.player, this.clock);
  3339. assert.equal(
  3340. this.player.tech_.hls.bandwidth,
  3341. 4194304,
  3342. 'uses default bandwidth when no option to use stored bandwidth'
  3343. );
  3344. assert.notOk(
  3345. this.player.tech_.hls.throughput,
  3346. 'no throughput when no option to use stored throughput'
  3347. );
  3348. assert.equal(bandwidthUsageEvents, 0, 'no bandwidth usage event');
  3349. assert.equal(throughputUsageEvents, 0, 'no throughput usage event');
  3350. const origHlsOptions = videojs.options.hls;
  3351. videojs.options.hls = {
  3352. useBandwidthFromLocalStorage: true
  3353. };
  3354. this.player = createPlayer();
  3355. this.player.tech_.on('usage', usageListener);
  3356. this.player.src({
  3357. src: 'manifest/master.m3u8',
  3358. type: 'application/vnd.apple.mpegurl'
  3359. });
  3360. openMediaSource(this.player, this.clock);
  3361. assert.equal(this.player.tech_.hls.bandwidth, 33, 'retrieved stored bandwidth');
  3362. assert.equal(this.player.tech_.hls.throughput, 44, 'retrieved stored throughput');
  3363. assert.equal(bandwidthUsageEvents, 1, 'one bandwidth usage event');
  3364. assert.equal(throughputUsageEvents, 1, 'one throughput usage event');
  3365. videojs.options.hls = origHlsOptions;
  3366. });
  3367. QUnit[testOrSkip](
  3368. 'does not retrieve bandwidth and throughput from localStorage when stored value is not as expected',
  3369. function(assert) {
  3370. // bad value
  3371. window.localStorage.setItem(LOCAL_STORAGE_KEY, 'a');
  3372. let bandwidthUsageEvents = 0;
  3373. let throughputUsageEvents = 0;
  3374. const usageListener = (event) => {
  3375. if (event.name === 'hls-bandwidth-from-local-storage') {
  3376. bandwidthUsageEvents++;
  3377. }
  3378. if (event.name === 'hls-throughput-from-local-storage') {
  3379. throughputUsageEvents++;
  3380. }
  3381. };
  3382. const origHlsOptions = videojs.options.hls;
  3383. videojs.options.hls = {
  3384. useBandwidthFromLocalStorage: true
  3385. };
  3386. // values must be stored before player is created, otherwise defaults are provided
  3387. this.player = createPlayer();
  3388. this.player.tech_.on('usage', usageListener);
  3389. this.player.src({
  3390. src: 'manifest/master.m3u8',
  3391. type: 'application/vnd.apple.mpegurl'
  3392. });
  3393. openMediaSource(this.player, this.clock);
  3394. assert.equal(
  3395. this.player.tech_.hls.bandwidth,
  3396. 4194304,
  3397. 'uses default bandwidth when bandwidth value retrieved'
  3398. );
  3399. assert.notOk(this.player.tech_.hls.throughput, 'no throughput value retrieved');
  3400. assert.equal(bandwidthUsageEvents, 0, 'no bandwidth usage event');
  3401. assert.equal(throughputUsageEvents, 0, 'no throughput usage event');
  3402. videojs.options.hls = origHlsOptions;
  3403. }
  3404. );
  3405. QUnit.test(
  3406. 'convertToProgramTime will return error if time is not buffered',
  3407. function(assert) {
  3408. const done = assert.async();
  3409. this.player.src({
  3410. src: 'manifest/playlist.m3u8',
  3411. type: 'application/vnd.apple.mpegurl'
  3412. });
  3413. this.clock.tick(1);
  3414. openMediaSource(this.player, this.clock);
  3415. // media
  3416. this.standardXHRResponse(this.requests.shift());
  3417. // ts
  3418. this.standardXHRResponse(this.requests.shift());
  3419. this.player.vhs.convertToProgramTime(3, (err, programTime) => {
  3420. assert.deepEqual(
  3421. err,
  3422. {
  3423. message:
  3424. 'Accurate programTime could not be determined.' +
  3425. ' Please seek to e.seekTime and try again',
  3426. seekTime: 0
  3427. },
  3428. 'error is returned as time is not buffered'
  3429. );
  3430. done();
  3431. });
  3432. }
  3433. );
  3434. QUnit.test('convertToProgramTime will return stream time if buffered', function(assert) {
  3435. const done = assert.async();
  3436. this.player.src({
  3437. src: 'manifest/master.m3u8',
  3438. type: 'application/vnd.apple.mpegurl'
  3439. });
  3440. this.clock.tick(1);
  3441. openMediaSource(this.player, this.clock);
  3442. this.player.tech_.hls.bandwidth = 20e10;
  3443. // master
  3444. this.standardXHRResponse(this.requests[0]);
  3445. // media.m3u8
  3446. this.standardXHRResponse(this.requests[1]);
  3447. const mpc = this.player.vhs.masterPlaylistController_;
  3448. mpc.mainSegmentLoader_.one('appending', () => {
  3449. const videoBuffer = mpc.sourceUpdater_.videoBuffer;
  3450. // since we don't run through the transmuxer, we have to manually trigger the timing
  3451. // info callback
  3452. videoBuffer.trigger({
  3453. type: 'videoSegmentTimingInfo',
  3454. videoSegmentTimingInfo: {
  3455. prependedGopDuration: 0,
  3456. start: {
  3457. presentation: 0
  3458. },
  3459. end: {
  3460. presentation: 1
  3461. }
  3462. }
  3463. });
  3464. });
  3465. return requestAndAppendSegment({
  3466. request: this.requests[2],
  3467. mediaSource: mpc.mediaSource,
  3468. segmentLoader: mpc.mainSegmentLoader_,
  3469. clock: this.clock
  3470. }).then(() => {
  3471. // ts
  3472. this.standardXHRResponse(this.requests[3], muxedSegment());
  3473. this.player.vhs.convertToProgramTime(0.01, (err, programTime) => {
  3474. assert.notOk(err, 'no errors');
  3475. assert.equal(
  3476. programTime.mediaSeconds,
  3477. 0.01,
  3478. 'returned the stream time of the source'
  3479. );
  3480. done();
  3481. });
  3482. });
  3483. });
  3484. QUnit.test(
  3485. 'seekToProgramTime will error if live stream has not started',
  3486. function(assert) {
  3487. this.player.src({
  3488. src: 'manifest/program-date-time.m3u8',
  3489. type: 'application/x-mpegurl'
  3490. });
  3491. this.clock.tick(1);
  3492. openMediaSource(this.player, this.clock);
  3493. // media
  3494. this.standardXHRResponse(this.requests.shift());
  3495. this.player.vhs.seekToProgramTime(
  3496. '2018-10-12T22:33:49.037+00:00',
  3497. (err, newTime) => {
  3498. assert.equal(
  3499. err.message,
  3500. 'player must be playing a live stream to start buffering',
  3501. 'error is returned when live stream has not started'
  3502. );
  3503. }
  3504. );
  3505. this.player.play();
  3506. // trigger playing with non-existent content
  3507. this.player.tech_.trigger('playing');
  3508. // wait for playlist refresh
  3509. this.clock.tick(4 * 1000 + 1);
  3510. // ts
  3511. this.standardXHRResponse(this.requests.shift(), muxedSegment());
  3512. this.player.vhs.seekToProgramTime(
  3513. '2018-10-12T22:33:49.037+00:00',
  3514. (err, newTime) => {
  3515. assert.equal(
  3516. err.message,
  3517. '2018-10-12T22:33:49.037+00:00 is not buffered yet. Try again',
  3518. 'error returned if time has not been buffered'
  3519. );
  3520. }
  3521. );
  3522. }
  3523. );
  3524. QUnit.test('seekToProgramTime seek to time if buffered', function(assert) {
  3525. const done = assert.async();
  3526. this.player.src({
  3527. src: 'manifest/program-date-time.m3u8',
  3528. type: 'application/x-mpegurl'
  3529. });
  3530. this.clock.tick(1);
  3531. openMediaSource(this.player, this.clock);
  3532. // media
  3533. this.standardXHRResponse(this.requests.shift());
  3534. this.player.play();
  3535. // trigger playing with non-existent content
  3536. this.player.tech_.trigger('playing');
  3537. // wait for playlist refresh
  3538. this.clock.tick(2 * 1000 + 1);
  3539. const mpc = this.player.vhs.masterPlaylistController_;
  3540. mpc.mainSegmentLoader_.one('appending', () => {
  3541. const videoBuffer = mpc.sourceUpdater_.videoBuffer;
  3542. // must fake the call to videoTimingInfo as the segment isn't transmuxed in the test
  3543. videoBuffer.trigger({
  3544. type: 'videoSegmentTimingInfo',
  3545. videoSegmentTimingInfo: {
  3546. start: {
  3547. presentation: 0
  3548. },
  3549. end: {
  3550. presentation: 0.3333
  3551. },
  3552. baseMediaDecodeTime: 0,
  3553. prependedContentDuration: 0
  3554. }
  3555. });
  3556. });
  3557. return requestAndAppendSegment({
  3558. request: this.requests.shift(),
  3559. mediaSource: mpc.mediaSource,
  3560. segmentLoader: mpc.mainSegmentLoader_,
  3561. clock: this.clock
  3562. }).then(() => {
  3563. this.player.vhs.seekToProgramTime(
  3564. '2018-10-12T22:33:49.037+00:00',
  3565. (err, newTime) => {
  3566. assert.notOk(
  3567. err,
  3568. 'no error returned'
  3569. );
  3570. assert.equal(
  3571. newTime,
  3572. 0,
  3573. 'newTime is returned as the time the player seeked to'
  3574. );
  3575. done();
  3576. }
  3577. );
  3578. // This allows seek to take affect
  3579. this.clock.tick(2);
  3580. });
  3581. });
  3582. QUnit.module('HLS Integration', {
  3583. beforeEach(assert) {
  3584. this.env = useFakeEnvironment(assert);
  3585. this.requests = this.env.requests;
  3586. this.mse = useFakeMediaSource();
  3587. this.tech = new (videojs.getTech('Html5'))({});
  3588. this.clock = this.env.clock;
  3589. this.standardXHRResponse = (request, data) => {
  3590. standardXHRResponse(request, data);
  3591. // Because SegmentLoader#fillBuffer_ is now scheduled asynchronously
  3592. // we have to use clock.tick to get the expected side effects of
  3593. // SegmentLoader#handleAppendsDone_
  3594. this.clock.tick(1);
  3595. };
  3596. videojs.HlsHandler.prototype.setupQualityLevels_ = () => {};
  3597. },
  3598. afterEach() {
  3599. this.env.restore();
  3600. this.mse.restore();
  3601. window.localStorage.clear();
  3602. videojs.HlsHandler.prototype.setupQualityLevels_ = ogHlsHandlerSetupQualityLevels;
  3603. }
  3604. });
  3605. QUnit.test('aborts all in-flight work when disposed', function(assert) {
  3606. const hls = HlsSourceHandler.handleSource({
  3607. src: 'manifest/master.m3u8',
  3608. type: 'application/vnd.apple.mpegurl'
  3609. }, this.tech);
  3610. hls.mediaSource.trigger('sourceopen');
  3611. // master
  3612. this.standardXHRResponse(this.requests.shift());
  3613. // media
  3614. this.standardXHRResponse(this.requests.shift());
  3615. hls.dispose();
  3616. assert.ok(this.requests[0].aborted, 'aborted the old segment request');
  3617. hls.mediaSource.sourceBuffers.forEach(sourceBuffer => {
  3618. const lastUpdate = sourceBuffer.updates_[sourceBuffer.updates_.length - 1];
  3619. assert.ok(lastUpdate.abort, 'aborted the source buffer');
  3620. });
  3621. });
  3622. QUnit.test('stats are reset on dispose', function(assert) {
  3623. const done = assert.async();
  3624. const hls = HlsSourceHandler.handleSource({
  3625. src: 'manifest/master.m3u8',
  3626. type: 'application/vnd.apple.mpegurl'
  3627. }, this.tech);
  3628. hls.mediaSource.trigger('sourceopen');
  3629. // master
  3630. this.standardXHRResponse(this.requests.shift());
  3631. // media
  3632. this.standardXHRResponse(this.requests.shift());
  3633. const segment = muxedSegment();
  3634. // copy the byte length since the segment bytes get cleared out
  3635. const segmentByteLength = segment.byteLength;
  3636. assert.ok(segmentByteLength, 'the segment has some number of bytes');
  3637. // segment 0
  3638. this.standardXHRResponse(this.requests.shift(), segment);
  3639. hls.masterPlaylistController_.mainSegmentLoader_.on('appending', () => {
  3640. assert.equal(hls.stats.mediaBytesTransferred, segmentByteLength, 'stat is set');
  3641. hls.dispose();
  3642. assert.equal(hls.stats.mediaBytesTransferred, 0, 'stat is reset');
  3643. done();
  3644. });
  3645. });
  3646. // mocking the fullscreenElement no longer works, find another way to mock
  3647. // fullscreen behavior(without user gesture)
  3648. QUnit.skip('detects fullscreen and triggers a smooth quality change', function(assert) {
  3649. const hls = HlsSourceHandler.handleSource({
  3650. src: 'manifest/master.m3u8',
  3651. type: 'application/vnd.apple.mpegurl'
  3652. }, this.tech);
  3653. let qualityChanges = 0;
  3654. let fullscreenElementName;
  3655. ['fullscreenElement', 'webkitFullscreenElement',
  3656. 'mozFullScreenElement', 'msFullscreenElement'].forEach((name) => {
  3657. if (!fullscreenElementName && !document.hasOwnProperty(name)) {
  3658. fullscreenElementName = name;
  3659. }
  3660. });
  3661. hls.masterPlaylistController_.smoothQualityChange_ = function() {
  3662. qualityChanges++;
  3663. };
  3664. // take advantage of capability detection to mock fullscreen activation
  3665. document[fullscreenElementName] = this.tech.el();
  3666. Events.trigger(document, 'fullscreenchange');
  3667. assert.equal(qualityChanges, 1, 'made a fast quality change');
  3668. // don't do a fast quality change when returning from fullscreen;
  3669. // allow the video element to rescale the already buffered video
  3670. document[fullscreenElementName] = null;
  3671. Events.trigger(document, 'fullscreenchange');
  3672. assert.equal(qualityChanges, 1, 'did not make another quality change');
  3673. hls.dispose();
  3674. });
  3675. QUnit.test('downloads additional playlists if required', function(assert) {
  3676. const hls = HlsSourceHandler.handleSource({
  3677. src: 'manifest/master.m3u8',
  3678. type: 'application/vnd.apple.mpegurl'
  3679. }, this.tech);
  3680. // Make segment metadata noop since most test segments dont have real data
  3681. hls.masterPlaylistController_.mainSegmentLoader_.addSegmentMetadataCue_ = () => {};
  3682. hls.mediaSource.trigger('sourceopen');
  3683. hls.bandwidth = 1;
  3684. // master
  3685. this.standardXHRResponse(this.requests[0]);
  3686. // media
  3687. this.standardXHRResponse(this.requests[1]);
  3688. const originalPlaylist = hls.playlists.media();
  3689. const mpc = hls.masterPlaylistController_;
  3690. mpc.mainSegmentLoader_.mediaIndex = 0;
  3691. return requestAndAppendSegment({
  3692. request: this.requests[2],
  3693. mediaSource: mpc.mediaSource,
  3694. segmentLoader: mpc.mainSegmentLoader_,
  3695. clock: this.clock,
  3696. // the playlist selection is revisited after a new segment is downloaded
  3697. bandwidth: 3000000,
  3698. tickClock: false
  3699. }).then(() => {
  3700. // update the buffer to reflect the appended segment, and have enough buffer to
  3701. // change playlist
  3702. this.tech.buffered = () => videojs.createTimeRanges([[0, 30]]);
  3703. this.clock.tick(1);
  3704. // new media
  3705. this.standardXHRResponse(this.requests[3]);
  3706. assert.ok(
  3707. (/manifest\/media\d+.m3u8$/).test(this.requests[3].url),
  3708. 'made a playlist request'
  3709. );
  3710. assert.notEqual(
  3711. originalPlaylist.resolvedUri,
  3712. hls.playlists.media().resolvedUri,
  3713. 'a new playlists was selected'
  3714. );
  3715. assert.ok(hls.playlists.media().segments, 'segments are now available');
  3716. // verify stats
  3717. assert.equal(hls.stats.bandwidth, 3000000, 'updated bandwidth');
  3718. hls.dispose();
  3719. });
  3720. });
  3721. QUnit.test('waits to download new segments until the media playlist is stable', function(assert) {
  3722. const hls = HlsSourceHandler.handleSource({
  3723. src: 'manifest/master.m3u8',
  3724. type: 'application/vnd.apple.mpegurl'
  3725. }, this.tech);
  3726. const mpc = hls.masterPlaylistController_;
  3727. mpc.mainSegmentLoader_.addSegmentMetadataCue_ = () => {};
  3728. hls.mediaSource.trigger('sourceopen');
  3729. // make sure we stay on the lowest variant
  3730. hls.bandwidth = 1;
  3731. // master
  3732. this.standardXHRResponse(this.requests.shift());
  3733. // media1
  3734. this.standardXHRResponse(this.requests.shift());
  3735. // put segment loader in walking forward mode
  3736. mpc.mainSegmentLoader_.mediaIndex = 0;
  3737. return requestAndAppendSegment({
  3738. request: this.requests.shift(),
  3739. mediaSource: mpc.mediaSource,
  3740. segmentLoader: mpc.mainSegmentLoader_,
  3741. clock: this.clock,
  3742. // bandwidth is high enough to switch playlists
  3743. bandwidth: Number.MAX_VALUE,
  3744. tickClock: false
  3745. }).then(() => {
  3746. // update the buffer to reflect the appended segment, and have enough buffer to
  3747. // change playlist
  3748. this.tech.buffered = () => videojs.createTimeRanges([[0, 30]]);
  3749. this.clock.tick(1);
  3750. assert.equal(this.requests.length, 1, 'only the playlist request outstanding');
  3751. this.clock.tick(10 * 1000);
  3752. assert.equal(this.requests.length, 1, 'delays segment fetching');
  3753. // another media playlist
  3754. this.standardXHRResponse(this.requests.shift());
  3755. this.clock.tick(10 * 1000);
  3756. assert.equal(this.requests.length, 1, 'resumes segment fetching');
  3757. // verify stats
  3758. assert.equal(hls.stats.bandwidth, Infinity, 'bandwidth is set to infinity');
  3759. hls.dispose();
  3760. });
  3761. });
  3762. QUnit.test('live playlist starts three target durations before live', function(assert) {
  3763. const hls = HlsSourceHandler.handleSource({
  3764. src: 'manifest/master.m3u8',
  3765. type: 'application/vnd.apple.mpegurl'
  3766. }, this.tech);
  3767. hls.mediaSource.trigger('sourceopen');
  3768. this.requests.shift().respond(
  3769. 200, null,
  3770. '#EXTM3U\n' +
  3771. '#EXT-X-MEDIA-SEQUENCE:101\n' +
  3772. '#EXT-X-TARGETDURATION:10\n' +
  3773. '#EXTINF:10,\n' +
  3774. '0.ts\n' +
  3775. '#EXTINF:10,\n' +
  3776. '1.ts\n' +
  3777. '#EXTINF:10,\n' +
  3778. '2.ts\n' +
  3779. '#EXTINF:10,\n' +
  3780. '3.ts\n' +
  3781. '#EXTINF:10,\n' +
  3782. '4.ts\n'
  3783. );
  3784. assert.equal(this.requests.length, 0, 'no outstanding segment request');
  3785. this.tech.paused = function() {
  3786. return false;
  3787. };
  3788. let techCurrentTime = 0;
  3789. this.tech.setCurrentTime = function(ct) {
  3790. techCurrentTime = ct;
  3791. };
  3792. this.tech.readyState = () => 4;
  3793. this.tech.trigger('play');
  3794. this.clock.tick(1);
  3795. assert.equal(
  3796. hls.seekable().end(0),
  3797. 20,
  3798. 'seekable end is three target durations from playlist end'
  3799. );
  3800. assert.equal(
  3801. techCurrentTime,
  3802. hls.seekable().end(0),
  3803. 'seeked to the seekable end'
  3804. );
  3805. assert.equal(this.requests.length, 1, 'begins buffering');
  3806. hls.dispose();
  3807. });
  3808. QUnit.test(
  3809. 'uses user defined selectPlaylist from HlsHandler if specified',
  3810. function(assert) {
  3811. const origStandardPlaylistSelector = Hls.STANDARD_PLAYLIST_SELECTOR;
  3812. let defaultSelectPlaylistCount = 0;
  3813. Hls.STANDARD_PLAYLIST_SELECTOR = () => defaultSelectPlaylistCount++;
  3814. let hls = HlsSourceHandler.handleSource({
  3815. src: 'manifest/master.m3u8',
  3816. type: 'application/vnd.apple.mpegurl'
  3817. }, this.tech);
  3818. hls.masterPlaylistController_.selectPlaylist();
  3819. assert.equal(defaultSelectPlaylistCount, 1, 'uses default playlist selector');
  3820. defaultSelectPlaylistCount = 0;
  3821. let newSelectPlaylistCount = 0;
  3822. const newSelectPlaylist = () => newSelectPlaylistCount++;
  3823. HlsHandler.prototype.selectPlaylist = newSelectPlaylist;
  3824. hls.dispose();
  3825. hls = HlsSourceHandler.handleSource({
  3826. src: 'manifest/master.m3u8',
  3827. type: 'application/vnd.apple.mpegurl'
  3828. }, this.tech);
  3829. hls.masterPlaylistController_.selectPlaylist();
  3830. assert.equal(defaultSelectPlaylistCount, 0, 'standard playlist selector not run');
  3831. assert.equal(newSelectPlaylistCount, 1, 'uses overridden playlist selector');
  3832. newSelectPlaylistCount = 0;
  3833. let setSelectPlaylistCount = 0;
  3834. hls.selectPlaylist = () => setSelectPlaylistCount++;
  3835. hls.masterPlaylistController_.selectPlaylist();
  3836. assert.equal(defaultSelectPlaylistCount, 0, 'standard playlist selector not run');
  3837. assert.equal(newSelectPlaylistCount, 0, 'overridden playlist selector not run');
  3838. assert.equal(setSelectPlaylistCount, 1, 'uses set playlist selector');
  3839. Hls.STANDARD_PLAYLIST_SELECTOR = origStandardPlaylistSelector;
  3840. delete HlsHandler.prototype.selectPlaylist;
  3841. hls.dispose();
  3842. }
  3843. );
  3844. QUnit.module('HLS - Encryption', {
  3845. beforeEach(assert) {
  3846. this.env = useFakeEnvironment(assert);
  3847. this.requests = this.env.requests;
  3848. this.mse = useFakeMediaSource();
  3849. this.tech = new (videojs.getTech('Html5'))({});
  3850. this.clock = this.env.clock;
  3851. this.standardXHRResponse = (request, data) => {
  3852. standardXHRResponse(request, data);
  3853. // Because SegmentLoader#fillBuffer_ is now scheduled asynchronously
  3854. // we have to use clock.tick to get the expected side effects of
  3855. // SegmentLoader#handleAppendsDone_
  3856. this.clock.tick(1);
  3857. };
  3858. videojs.HlsHandler.prototype.setupQualityLevels_ = () => {};
  3859. },
  3860. afterEach() {
  3861. this.env.restore();
  3862. this.mse.restore();
  3863. window.localStorage.clear();
  3864. videojs.HlsHandler.prototype.setupQualityLevels_ = ogHlsHandlerSetupQualityLevels;
  3865. }
  3866. });
  3867. QUnit.test('blacklists playlist if key requests fail', function(assert) {
  3868. const hls = HlsSourceHandler.handleSource({
  3869. src: 'manifest/encrypted-master.m3u8',
  3870. type: 'application/vnd.apple.mpegurl'
  3871. }, this.tech);
  3872. hls.mediaSource.trigger('sourceopen');
  3873. this.requests.shift()
  3874. .respond(
  3875. 200, null,
  3876. '#EXTM3U\n' +
  3877. '#EXT-X-STREAM-INF:BANDWIDTH=1000\n' +
  3878. 'media.m3u8\n' +
  3879. '#EXT-X-STREAM-INF:BANDWIDTH=1\n' +
  3880. 'media1.m3u8\n'
  3881. );
  3882. this.requests.shift()
  3883. .respond(
  3884. 200, null,
  3885. '#EXTM3U\n' +
  3886. '#EXT-X-KEY:METHOD=AES-128,URI="htts://priv.example.com/key.php?r=52"\n' +
  3887. '#EXTINF:2.833,\n' +
  3888. 'http://media.example.com/fileSequence52-A.ts\n' +
  3889. '#EXT-X-KEY:METHOD=AES-128,URI="htts://priv.example.com/key.php?r=53"\n' +
  3890. '#EXTINF:15.0,\n' +
  3891. 'http://media.example.com/fileSequence53-A.ts\n' +
  3892. '#EXT-X-ENDLIST\n'
  3893. );
  3894. this.clock.tick(1);
  3895. // segment 1
  3896. if (/key\.php/i.test(this.requests[0].url)) {
  3897. this.standardXHRResponse(this.requests.pop());
  3898. } else {
  3899. this.standardXHRResponse(this.requests.shift());
  3900. }
  3901. // fail key
  3902. this.requests.shift().respond(404);
  3903. assert.ok(
  3904. hls.playlists.media().excludeUntil > 0,
  3905. 'playlist blacklisted'
  3906. );
  3907. assert.equal(this.env.log.warn.calls, 1, 'logged warning for blacklist');
  3908. });
  3909. QUnit.test(
  3910. 'treats invalid keys as a key request failure and blacklists playlist',
  3911. function(assert) {
  3912. const hls = HlsSourceHandler.handleSource({
  3913. src: 'manifest/encrypted-master.m3u8',
  3914. type: 'application/vnd.apple.mpegurl'
  3915. }, this.tech);
  3916. hls.mediaSource.trigger('sourceopen');
  3917. this.requests.shift()
  3918. .respond(
  3919. 200, null,
  3920. '#EXTM3U\n' +
  3921. '#EXT-X-STREAM-INF:BANDWIDTH=1000\n' +
  3922. 'media.m3u8\n' +
  3923. '#EXT-X-STREAM-INF:BANDWIDTH=1\n' +
  3924. 'media1.m3u8\n'
  3925. );
  3926. this.requests.shift()
  3927. .respond(
  3928. 200, null,
  3929. '#EXTM3U\n' +
  3930. '#EXT-X-MEDIA-SEQUENCE:5\n' +
  3931. '#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=52"\n' +
  3932. '#EXTINF:2.833,\n' +
  3933. 'http://media.example.com/fileSequence52-A.ts\n' +
  3934. '#EXT-X-KEY:METHOD=NONE\n' +
  3935. '#EXTINF:15.0,\n' +
  3936. 'http://media.example.com/fileSequence52-B.ts\n' +
  3937. '#EXT-X-ENDLIST\n'
  3938. );
  3939. this.clock.tick(1);
  3940. // segment request
  3941. this.standardXHRResponse(this.requests.pop());
  3942. assert.equal(
  3943. this.requests[0].url,
  3944. 'https://priv.example.com/key.php?r=52',
  3945. 'requested the key'
  3946. );
  3947. // keys *should* be 16 bytes long -- this one is too small
  3948. this.requests[0].response = new Uint8Array(1).buffer;
  3949. this.requests.shift().respond(200, null, '');
  3950. this.clock.tick(1);
  3951. // blacklist this playlist
  3952. assert.ok(
  3953. hls.playlists.media().excludeUntil > 0,
  3954. 'blacklisted playlist'
  3955. );
  3956. assert.equal(this.env.log.warn.calls, 1, 'logged warning for blacklist');
  3957. // verify stats
  3958. assert.equal(hls.stats.mediaBytesTransferred, 1024, '1024 bytes');
  3959. assert.equal(hls.stats.mediaRequests, 1, '1 request');
  3960. }
  3961. );
  3962. QUnit.module('videojs-contrib-hls isolated functions');
  3963. QUnit.test('emeKeySystems adds content types for all keySystems', function(assert) {
  3964. assert.deepEqual(
  3965. emeKeySystems(
  3966. { keySystem1: {}, keySystem2: {} },
  3967. { attributes: { CODECS: 'some-video-codec' } },
  3968. { attributes: { CODECS: 'some-audio-codec' } }
  3969. ),
  3970. {
  3971. keySystem1: {
  3972. audioContentType: 'audio/mp4; codecs="some-audio-codec"',
  3973. videoContentType: 'video/mp4; codecs="some-video-codec"'
  3974. },
  3975. keySystem2: {
  3976. audioContentType: 'audio/mp4; codecs="some-audio-codec"',
  3977. videoContentType: 'video/mp4; codecs="some-video-codec"'
  3978. }
  3979. },
  3980. 'added content types'
  3981. );
  3982. });
  3983. QUnit.test('emeKeySystems retains non content type properties', function(assert) {
  3984. assert.deepEqual(
  3985. emeKeySystems(
  3986. { keySystem1: { url: '1' }, keySystem2: { url: '2'} },
  3987. { attributes: { CODECS: 'some-video-codec' } },
  3988. { attributes: { CODECS: 'some-audio-codec' } }
  3989. ),
  3990. {
  3991. keySystem1: {
  3992. url: '1',
  3993. audioContentType: 'audio/mp4; codecs="some-audio-codec"',
  3994. videoContentType: 'video/mp4; codecs="some-video-codec"'
  3995. },
  3996. keySystem2: {
  3997. url: '2',
  3998. audioContentType: 'audio/mp4; codecs="some-audio-codec"',
  3999. videoContentType: 'video/mp4; codecs="some-video-codec"'
  4000. }
  4001. },
  4002. 'retained options'
  4003. );
  4004. });
  4005. QUnit.test('emeKeySystems overwrites content types', function(assert) {
  4006. assert.deepEqual(
  4007. emeKeySystems(
  4008. {
  4009. keySystem1: {
  4010. audioContentType: 'a',
  4011. videoContentType: 'b'
  4012. },
  4013. keySystem2: {
  4014. audioContentType: 'c',
  4015. videoContentType: 'd'
  4016. }
  4017. },
  4018. { attributes: { CODECS: 'some-video-codec' } },
  4019. { attributes: { CODECS: 'some-audio-codec' } }
  4020. ),
  4021. {
  4022. keySystem1: {
  4023. audioContentType: 'audio/mp4; codecs="some-audio-codec"',
  4024. videoContentType: 'video/mp4; codecs="some-video-codec"'
  4025. },
  4026. keySystem2: {
  4027. audioContentType: 'audio/mp4; codecs="some-audio-codec"',
  4028. videoContentType: 'video/mp4; codecs="some-video-codec"'
  4029. }
  4030. },
  4031. 'overwrote content types'
  4032. );
  4033. });
  4034. QUnit.test('simpleTypeFromSourceType converts HLS mime types to hls', function(assert) {
  4035. assert.equal(
  4036. simpleTypeFromSourceType('aPplicatiOn/x-MPegUrl'),
  4037. 'hls',
  4038. 'supports application/x-mpegurl'
  4039. );
  4040. assert.equal(
  4041. simpleTypeFromSourceType('aPplicatiOn/VnD.aPPle.MpEgUrL'),
  4042. 'hls',
  4043. 'supports application/vnd.apple.mpegurl'
  4044. );
  4045. });
  4046. QUnit.test('simpleTypeFromSourceType converts DASH mime type to dash', function(assert) {
  4047. assert.equal(
  4048. simpleTypeFromSourceType('aPplication/dAsh+xMl'),
  4049. 'dash',
  4050. 'supports application/dash+xml'
  4051. );
  4052. });
  4053. QUnit.test(
  4054. 'simpleTypeFromSourceType does not convert non HLS/DASH mime types',
  4055. function(assert) {
  4056. assert.notOk(simpleTypeFromSourceType('video/mp4'), 'does not support video/mp4');
  4057. assert.notOk(simpleTypeFromSourceType('video/x-flv'), 'does not support video/x-flv');
  4058. }
  4059. );