@@ -1642,9 +1642,73 @@ export class PlaylistController extends videojs.EventTarget {
16421642 return this . seekable_ ;
16431643 }
16441644
1645- onSyncInfoUpdate_ ( ) {
1646- let audioSeekable ;
1645+ getSeekableRange_ ( playlistLoader , mediaType ) {
1646+ const media = playlistLoader . media ( ) ;
1647+
1648+ if ( ! media ) {
1649+ return null ;
1650+ }
1651+
1652+ const mediaSequenceSync = this . syncController_ . getMediaSequenceSync ( mediaType ) ;
1653+
1654+ if ( mediaSequenceSync && mediaSequenceSync . isReliable ) {
1655+ const start = mediaSequenceSync . start ;
1656+ const end = mediaSequenceSync . end ;
1657+
1658+ if ( ! isFinite ( start ) || ! isFinite ( end ) ) {
1659+ return null ;
1660+ }
1661+
1662+ const liveEdgeDelay = Vhs . Playlist . liveEdgeDelay ( this . mainPlaylistLoader_ . main , media ) ;
1663+
1664+ // Make sure our seekable end is not negative
1665+ const calculatedEnd = Math . max ( 0 , end - liveEdgeDelay ) ;
1666+
1667+ if ( calculatedEnd < start ) {
1668+ return null ;
1669+ }
1670+
1671+ return createTimeRanges ( [ [ start , calculatedEnd ] ] ) ;
1672+ }
1673+
1674+ const expired = this . syncController_ . getExpiredTime ( media , this . duration ( ) ) ;
1675+
1676+ if ( expired === null ) {
1677+ return null ;
1678+ }
1679+
1680+ const seekable = Vhs . Playlist . seekable (
1681+ media ,
1682+ expired ,
1683+ Vhs . Playlist . liveEdgeDelay ( this . mainPlaylistLoader_ . main , media )
1684+ ) ;
1685+
1686+ return seekable . length ? seekable : null ;
1687+ }
1688+
1689+ computeFinalSeekable_ ( mainSeekable , audioSeekable ) {
1690+ if ( ! audioSeekable ) {
1691+ return mainSeekable ;
1692+ }
1693+
1694+ const mainStart = mainSeekable . start ( 0 ) ;
1695+ const mainEnd = mainSeekable . end ( 0 ) ;
1696+ const audioStart = audioSeekable . start ( 0 ) ;
1697+ const audioEnd = audioSeekable . end ( 0 ) ;
16471698
1699+ if ( audioStart > mainEnd || mainStart > audioEnd ) {
1700+ // Seekables are far apart, rely on main
1701+ return mainSeekable ;
1702+ }
1703+
1704+ // Return the overlapping seekable range
1705+ return createTimeRanges ( [ [
1706+ Math . max ( mainStart , audioStart ) ,
1707+ Math . min ( mainEnd , audioEnd )
1708+ ] ] ) ;
1709+ }
1710+
1711+ onSyncInfoUpdate_ ( ) {
16481712 // TODO check for creation of both source buffers before updating seekable
16491713 //
16501714 // A fix was made to this function where a check for
@@ -1668,87 +1732,45 @@ export class PlaylistController extends videojs.EventTarget {
16681732 return ;
16691733 }
16701734
1671- let media = this . mainPlaylistLoader_ . media ( ) ;
1672-
1673- if ( ! media ) {
1674- return ;
1675- }
1676-
1677- let expired = this . syncController_ . getExpiredTime ( media , this . duration ( ) ) ;
1735+ const mainSeekable = this . getSeekableRange_ ( this . mainPlaylistLoader_ , 'main' ) ;
16781736
1679- if ( expired === null ) {
1680- // not enough information to update seekable
1737+ if ( ! mainSeekable ) {
16811738 return ;
16821739 }
16831740
1684- const main = this . mainPlaylistLoader_ . main ;
1685- const mainSeekable = Vhs . Playlist . seekable (
1686- media ,
1687- expired ,
1688- Vhs . Playlist . liveEdgeDelay ( main , media )
1689- ) ;
1690-
1691- if ( mainSeekable . length === 0 ) {
1692- return ;
1693- }
1741+ let audioSeekable ;
16941742
16951743 if ( this . mediaTypes_ . AUDIO . activePlaylistLoader ) {
1696- media = this . mediaTypes_ . AUDIO . activePlaylistLoader . media ( ) ;
1697- expired = this . syncController_ . getExpiredTime ( media , this . duration ( ) ) ;
1698-
1699- if ( expired === null ) {
1700- return ;
1701- }
1744+ audioSeekable = this . getSeekableRange_ ( this . mediaTypes_ . AUDIO . activePlaylistLoader , 'audio' ) ;
17021745
1703- audioSeekable = Vhs . Playlist . seekable (
1704- media ,
1705- expired ,
1706- Vhs . Playlist . liveEdgeDelay ( main , media )
1707- ) ;
1708-
1709- if ( audioSeekable . length === 0 ) {
1746+ if ( ! audioSeekable ) {
17101747 return ;
17111748 }
17121749 }
17131750
1714- let oldEnd ;
1715- let oldStart ;
1751+ const oldSeekable = this . seekable_ ;
17161752
1717- if ( this . seekable_ && this . seekable_ . length ) {
1718- oldEnd = this . seekable_ . end ( 0 ) ;
1719- oldStart = this . seekable_ . start ( 0 ) ;
1720- }
1753+ this . seekable_ = this . computeFinalSeekable_ ( mainSeekable , audioSeekable ) ;
17211754
1722- if ( ! audioSeekable ) {
1723- // seekable has been calculated based on buffering video data so it
1724- // can be returned directly
1725- this . seekable_ = mainSeekable ;
1726- } else if ( audioSeekable . start ( 0 ) > mainSeekable . end ( 0 ) ||
1727- mainSeekable . start ( 0 ) > audioSeekable . end ( 0 ) ) {
1728- // seekables are pretty far off, rely on main
1729- this . seekable_ = mainSeekable ;
1730- } else {
1731- this . seekable_ = createTimeRanges ( [ [
1732- ( audioSeekable . start ( 0 ) > mainSeekable . start ( 0 ) ) ? audioSeekable . start ( 0 ) :
1733- mainSeekable . start ( 0 ) ,
1734- ( audioSeekable . end ( 0 ) < mainSeekable . end ( 0 ) ) ? audioSeekable . end ( 0 ) :
1735- mainSeekable . end ( 0 )
1736- ] ] ) ;
1755+ if ( ! this . seekable_ ) {
1756+ return ;
17371757 }
17381758
1739- // seekable is the same as last time
1740- if ( this . seekable_ && this . seekable_ . length ) {
1741- if ( this . seekable_ . end ( 0 ) === oldEnd && this . seekable_ . start ( 0 ) === oldStart ) {
1759+ if ( oldSeekable && oldSeekable . length && this . seekable_ . length ) {
1760+ if ( oldSeekable . start ( 0 ) === this . seekable_ . start ( 0 ) &&
1761+ oldSeekable . end ( 0 ) === this . seekable_ . end ( 0 ) ) {
1762+ // Seekable range hasn't changed
17421763 return ;
17431764 }
17441765 }
17451766
17461767 this . logger_ ( `seekable updated [${ Ranges . printableRange ( this . seekable_ ) } ]` ) ;
1768+
17471769 const metadata = {
17481770 seekableRanges : this . seekable_
17491771 } ;
17501772
1751- this . trigger ( { type : 'seekablerangeschanged' , metadata} ) ;
1773+ this . trigger ( { type : 'seekablerangeschanged' , metadata } ) ;
17521774 this . tech_ . trigger ( 'seekablechanged' ) ;
17531775 }
17541776
0 commit comments