@@ -30,6 +30,7 @@ import ChatHistoryEntry
3030import ChatMessageItemCommon
3131import WallpaperPreviewMedia
3232import TextNodeWithEntities
33+ import RangeSet
3334
3435private struct FetchControls {
3536 let fetch : ( Bool ) -> Void
@@ -1584,7 +1585,71 @@ public final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTr
15841585 }
15851586 }
15861587 } else if let file = media as? TelegramMediaFile {
1587- updatedStatusSignal = combineLatest ( messageMediaFileStatus ( context: context, messageId: message. id, file: file, adjustForVideoThumbnail: true ) , context. account. pendingMessageManager. pendingMessageStatus ( message. id) |> map { $0. 0 } )
1588+ if NativeVideoContent . isHLSVideo ( file: file) , let minimizedQuality = HLSVideoContent . minimizedHLSQuality ( file: . standalone( media: file) ) {
1589+ let postbox = context. account. postbox
1590+
1591+ let playlistStatusSignal = postbox. mediaBox. resourceStatus ( minimizedQuality. playlist. media. resource)
1592+ |> map { status -> MediaResourceStatus in
1593+ switch status {
1594+ case . Fetching, . Paused:
1595+ return . Fetching( isActive: true , progress: 0.0 )
1596+ case . Local:
1597+ return . Local
1598+ case . Remote:
1599+ return . Remote( progress: 0.0 )
1600+ }
1601+ }
1602+ |> distinctUntilChanged
1603+
1604+ updatedStatusSignal = playlistStatusSignal
1605+ |> mapToSignal { playlistStatus -> Signal < ( MediaResourceStatus , MediaResourceStatus ? ) , NoError > in
1606+ switch playlistStatus {
1607+ case . Fetching, . Paused:
1608+ return . single( ( . Fetching( isActive: true , progress: 0.0 ) , nil ) )
1609+ case . Remote:
1610+ return . single( ( . Remote( progress: 0.0 ) , nil ) )
1611+ case . Local:
1612+ break
1613+ }
1614+
1615+ return HLSVideoContent . minimizedHLSQualityPreloadData ( postbox: postbox, file: . message( message: MessageReference ( message) , media: file) , userLocation: . peer( message. id. peerId) , prefixSeconds: 10 , autofetchPlaylist: true )
1616+ |> mapToSignal { preloadData -> Signal < ( MediaResourceStatus , MediaResourceStatus ? ) , NoError > in
1617+ guard let preloadData else {
1618+ return . single( ( . Local, nil ) )
1619+ }
1620+
1621+ return postbox. mediaBox. resourceStatus ( preloadData. 0 . media. resource)
1622+ |> map { status -> Bool in
1623+ if case . Fetching = status {
1624+ return true
1625+ } else {
1626+ return false
1627+ }
1628+ }
1629+ |> distinctUntilChanged
1630+ |> mapToSignal { isFetching -> Signal < ( MediaResourceStatus , MediaResourceStatus ? ) , NoError > in
1631+ return postbox. mediaBox. resourceRangesStatus ( preloadData. 0 . media. resource)
1632+ |> map { status -> ( MediaResourceStatus , MediaResourceStatus ? ) in
1633+ let preloadRanges = RangeSet ( preloadData. 1 )
1634+ let intersection = status. intersection ( preloadRanges)
1635+ var totalLoaded : Int64 = 0
1636+ for range in intersection. ranges {
1637+ totalLoaded += range. upperBound - range. lowerBound
1638+ }
1639+ let preloadLength = preloadData. 1 . upperBound - preloadData. 1 . lowerBound
1640+ if totalLoaded >= preloadLength {
1641+ return ( . Local, nil )
1642+ } else if isFetching {
1643+ return ( . Fetching( isActive: true , progress: Float ( totalLoaded) / Float( preloadLength) ) , nil )
1644+ } else {
1645+ return ( . Remote( progress: 0.0 ) , nil )
1646+ }
1647+ }
1648+ }
1649+ }
1650+ }
1651+ } else {
1652+ updatedStatusSignal = combineLatest ( messageMediaFileStatus ( context: context, messageId: message. id, file: file, adjustForVideoThumbnail: true ) , context. account. pendingMessageManager. pendingMessageStatus ( message. id) |> map { $0. 0 } )
15881653 |> map { resourceStatus, pendingStatus -> ( MediaResourceStatus , MediaResourceStatus ? ) in
15891654 if let pendingStatus = pendingStatus {
15901655 var progress : Float = pendingStatus. progress. progress
@@ -1596,6 +1661,7 @@ public final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTr
15961661 } else {
15971662 return ( resourceStatus, nil )
15981663 }
1664+ }
15991665 }
16001666 } else if let wallpaper = media as? WallpaperPreviewMedia {
16011667 switch wallpaper. content {
@@ -1992,9 +2058,8 @@ public final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTr
19922058 file: . message( message: MessageReference ( message) , media: loadHLSRangeVideoFile) ,
19932059 userLocation: . peer( message. id. peerId) ,
19942060 prefixSeconds: 10 ,
1995- autofetchPlaylist: false
2061+ autofetchPlaylist: true
19962062 )
1997- //|> delay(2.0, queue: .mainQueue())
19982063 |> deliverOnMainQueue) . startStrict ( next: { [ weak strongSelf] preloadData in
19992064 guard let strongSelf else {
20002065 return
@@ -2237,9 +2302,9 @@ public final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTr
22372302 }
22382303 }
22392304
2240- if let file = self . media as? TelegramMediaFile , NativeVideoContent . isHLSVideo ( file: file) {
2305+ /* if let file = self.media as? TelegramMediaFile, NativeVideoContent.isHLSVideo(file: file) {
22412306 fetchStatus = .Local
2242- }
2307+ }*/
22432308
22442309 let formatting = DataSizeStringFormatting ( strings: strings, decimalSeparator: decimalSeparator)
22452310
@@ -2281,7 +2346,12 @@ public final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTr
22812346 badgeContent = nil
22822347 } else if wideLayout {
22832348 if let size = file. size, size > 0 && size != . max {
2284- let sizeString = " \( dataSizeString ( Int ( Float ( size) * progress) , forceDecimal: true , formatting: formatting) ) / \( dataSizeString ( size, forceDecimal: true , formatting: formatting) ) "
2349+ let sizeString : String
2350+ if NativeVideoContent . isHLSVideo ( file: file) {
2351+ sizeString = " \( Int ( progress * 100.0 ) ) % "
2352+ } else {
2353+ sizeString = " \( dataSizeString ( Int ( Float ( size) * progress) , forceDecimal: true , formatting: formatting) ) / \( dataSizeString ( size, forceDecimal: true , formatting: formatting) ) "
2354+ }
22852355 if let duration = file. duration, !message. flags. contains ( . Unsent) {
22862356 let durationString = file. isAnimated ? gifTitle : stringForDuration ( playerDuration > 0 ? playerDuration : Int32 ( duration) , position: playerPosition)
22872357 if isMediaStreamable ( message: message, media: file) {
@@ -2382,32 +2452,36 @@ public final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTr
23822452 badgeContent = . mediaDownload( backgroundColor: messageTheme. mediaDateAndStatusFillColor, foregroundColor: messageTheme. mediaDateAndStatusTextColor, duration: durationString, size: nil , muted: muted, active: false )
23832453 }
23842454 case . Remote, . Paused:
2385- state = . download( messageTheme. mediaOverlayControlColors. foregroundColor)
2386- if let file = media as? TelegramMediaFile , !file. isVideoSticker {
2387- do {
2388- let durationString = file. isAnimated ? gifTitle : stringForDuration ( playerDuration > 0 ? playerDuration : ( file. duration. flatMap { Int32 ( floor ( $0) ) } ?? 0 ) , position: playerPosition)
2389- if wideLayout {
2390- if isMediaStreamable ( message: message, media: file) , let fileSize = file. size, fileSize > 0 && fileSize != . max {
2391- state = automaticPlayback ? . none : . play( messageTheme. mediaOverlayControlColors. foregroundColor)
2392- badgeContent = . mediaDownload( backgroundColor: messageTheme. mediaDateAndStatusFillColor, foregroundColor: messageTheme. mediaDateAndStatusTextColor, duration: durationString, size: dataSizeString ( fileSize, formatting: formatting) , muted: muted, active: true )
2393- mediaDownloadState = . remote
2394- } else {
2395- state = automaticPlayback ? . none : state
2396- badgeContent = . mediaDownload( backgroundColor: messageTheme. mediaDateAndStatusFillColor, foregroundColor: messageTheme. mediaDateAndStatusTextColor, duration: durationString, size: nil , muted: muted, active: false )
2397- }
2398- } else {
2399- if isMediaStreamable ( message: message, media: file) {
2400- state = automaticPlayback ? . none : . play( messageTheme. mediaOverlayControlColors. foregroundColor)
2401- badgeContent = . text( inset: 12.0 , backgroundColor: messageTheme. mediaDateAndStatusFillColor, foregroundColor: messageTheme. mediaDateAndStatusTextColor, text: NSAttributedString ( string: durationString) , iconName: nil )
2402- mediaDownloadState = . compactRemote
2455+ if let file = media as? TelegramMediaFile , NativeVideoContent . isHLSVideo ( file: file) , let automaticDownload = self . automaticDownload, case . none = automaticDownload {
2456+ state = . play( messageTheme. mediaOverlayControlColors. foregroundColor)
2457+ } else {
2458+ state = . download( messageTheme. mediaOverlayControlColors. foregroundColor)
2459+ if let file = media as? TelegramMediaFile , !file. isVideoSticker {
2460+ do {
2461+ let durationString = file. isAnimated ? gifTitle : stringForDuration ( playerDuration > 0 ? playerDuration : ( file. duration. flatMap { Int32 ( floor ( $0) ) } ?? 0 ) , position: playerPosition)
2462+ if wideLayout {
2463+ if isMediaStreamable ( message: message, media: file) , let fileSize = file. size, fileSize > 0 && fileSize != . max {
2464+ state = automaticPlayback ? . none : . play( messageTheme. mediaOverlayControlColors. foregroundColor)
2465+ badgeContent = . mediaDownload( backgroundColor: messageTheme. mediaDateAndStatusFillColor, foregroundColor: messageTheme. mediaDateAndStatusTextColor, duration: durationString, size: dataSizeString ( fileSize, formatting: formatting) , muted: muted, active: true )
2466+ mediaDownloadState = . remote
2467+ } else {
2468+ state = automaticPlayback ? . none : state
2469+ badgeContent = . mediaDownload( backgroundColor: messageTheme. mediaDateAndStatusFillColor, foregroundColor: messageTheme. mediaDateAndStatusTextColor, duration: durationString, size: nil , muted: muted, active: false )
2470+ }
24032471 } else {
2404- state = automaticPlayback ? . none : state
2405- badgeContent = . text( inset: 0.0 , backgroundColor: messageTheme. mediaDateAndStatusFillColor, foregroundColor: messageTheme. mediaDateAndStatusTextColor, text: NSAttributedString ( string: durationString) , iconName: nil )
2472+ if isMediaStreamable ( message: message, media: file) {
2473+ state = automaticPlayback ? . none : . play( messageTheme. mediaOverlayControlColors. foregroundColor)
2474+ badgeContent = . text( inset: 12.0 , backgroundColor: messageTheme. mediaDateAndStatusFillColor, foregroundColor: messageTheme. mediaDateAndStatusTextColor, text: NSAttributedString ( string: durationString) , iconName: nil )
2475+ mediaDownloadState = . compactRemote
2476+ } else {
2477+ state = automaticPlayback ? . none : state
2478+ badgeContent = . text( inset: 0.0 , backgroundColor: messageTheme. mediaDateAndStatusFillColor, foregroundColor: messageTheme. mediaDateAndStatusTextColor, text: NSAttributedString ( string: durationString) , iconName: nil )
2479+ }
24062480 }
24072481 }
2482+ } else if let webpage = webpage, let automaticDownload = self . automaticDownload, case . full = automaticDownload, case let . Loaded( content) = webpage. content, content. type != " telegram_background " {
2483+ state = . play( messageTheme. mediaOverlayControlColors. foregroundColor)
24082484 }
2409- } else if let webpage = webpage, let automaticDownload = self . automaticDownload, case . full = automaticDownload, case let . Loaded( content) = webpage. content, content. type != " telegram_background " {
2410- state = . play( messageTheme. mediaOverlayControlColors. foregroundColor)
24112485 }
24122486 }
24132487 }
0 commit comments