@@ -119,13 +119,15 @@ public final class ChunkMediaPlayerPart {
119119 public let startTime : Double
120120 public let endTime : Double
121121 public let file : TempBoxFile
122+ public let clippedStartTime : Double ?
122123
123124 public var id : Id {
124125 return Id ( rawValue: self . file. path)
125126 }
126127
127- public init ( startTime: Double , endTime: Double , file: TempBoxFile ) {
128+ public init ( startTime: Double , clippedStartTime : Double ? = nil , endTime: Double , file: TempBoxFile ) {
128129 self . startTime = startTime
130+ self . clippedStartTime = clippedStartTime
129131 self . endTime = endTime
130132 self . file = file
131133 }
@@ -620,58 +622,54 @@ private final class ChunkMediaPlayerContext {
620622
621623 var validParts : [ ChunkMediaPlayerPart ] = [ ]
622624
625+ var minStartTime : Double = 0.0
623626 for i in 0 ..< self . partsState. parts. count {
624627 let part = self . partsState. parts [ i]
628+
629+ let partStartTime = max ( minStartTime, part. startTime)
630+ let partEndTime = max ( partStartTime, part. endTime)
631+ if partStartTime >= partEndTime {
632+ continue
633+ }
634+
625635 var partMatches = false
626- if timestamp >= part . startTime - 0.5 && timestamp < part . endTime + 0.5 {
636+ if timestamp >= partStartTime - 0.5 && timestamp < partEndTime + 0.5 {
627637 partMatches = true
628638 }
629639
630640 if partMatches {
631- validParts. append ( part)
641+ validParts. append ( ChunkMediaPlayerPart (
642+ startTime: part. startTime,
643+ clippedStartTime: partStartTime == part. startTime ? nil : partStartTime,
644+ endTime: part. endTime,
645+ file: part. file
646+ ) )
647+ minStartTime = max ( minStartTime, partEndTime)
632648 }
633649 }
650+
634651 if let lastValidPart = validParts. last {
635652 for i in 0 ..< self . partsState. parts. count {
636653 let part = self . partsState. parts [ i]
637- if lastValidPart !== part && part. startTime > lastValidPart. startTime && part. startTime <= lastValidPart. endTime + 0.5 {
638- validParts. append ( part)
639- break
640- }
641- }
642- }
643-
644- /*for i in 0 ..< self.partsState.parts.count {
645- let part = self.partsState.parts[i]
646- var partMatches = false
647- if timestamp >= part.startTime - 0.001 && timestamp < part.endTime - 0.001 {
648- partMatches = true
649- } else if part.startTime < 0.2 && timestamp < part.endTime - 0.001 {
650- partMatches = true
651- }
652-
653- if !partMatches, i != self.partsState.parts.count - 1, part.startTime >= 0.001, timestamp >= part.startTime {
654- let nextPart = self.partsState.parts[i + 1]
655- if timestamp < nextPart.endTime - 0.001 {
656- if part.endTime >= nextPart.startTime - 0.1 {
657- partMatches = true
658- }
659- }
660- }
661-
662- if partMatches {
663- validParts.append(part)
664654
665- inner: for lookaheadPart in self.partsState.parts {
666- if lookaheadPart.startTime >= part.endTime - 0.001 && lookaheadPart.startTime - 0.1 < part.endTime {
667- validParts.append(lookaheadPart)
668- break inner
669- }
655+ let partStartTime = max ( minStartTime, part. startTime)
656+ let partEndTime = max ( partStartTime, part. endTime)
657+ if partStartTime >= partEndTime {
658+ continue
670659 }
671660
672- break
661+ if lastValidPart !== part && partStartTime > ( lastValidPart. clippedStartTime ?? lastValidPart. startTime) && partStartTime <= lastValidPart. endTime + 0.5 {
662+ validParts. append ( ChunkMediaPlayerPart (
663+ startTime: part. startTime,
664+ clippedStartTime: partStartTime == part. startTime ? nil : partStartTime,
665+ endTime: part. endTime,
666+ file: part. file
667+ ) )
668+ minStartTime = max ( minStartTime, partEndTime)
669+ break
670+ }
673671 }
674- }*/
672+ }
675673
676674 if validParts. isEmpty, let initialSeekTimestamp = self . initialSeekTimestamp {
677675 for part in self . partsState. parts {
@@ -701,6 +699,8 @@ private final class ChunkMediaPlayerContext {
701699 self . initialSeekTimestamp = nil
702700 }
703701
702+ //print("validParts: \(validParts.map { "\($0.startTime) ... \($0.endTime)" })")
703+
704704 self . loadedState. partStates. removeAll ( where: { partState in
705705 if !validParts. contains ( where: { $0. id == partState. part. id } ) {
706706 return true
@@ -742,7 +742,13 @@ private final class ChunkMediaPlayerContext {
742742 for i in 0 ..< self . loadedState. partStates. count {
743743 let partState = self . loadedState. partStates [ i]
744744 if partState. mediaBuffersDisposable == nil {
745- partState. mediaBuffersDisposable = ( partState. frameSource. seek ( timestamp: i == 0 ? timestamp : 0.0 )
745+ let partSeekOffset : Double
746+ if let clippedStartTime = partState. part. clippedStartTime {
747+ partSeekOffset = clippedStartTime - partState. part. startTime
748+ } else {
749+ partSeekOffset = 0.0
750+ }
751+ partState. mediaBuffersDisposable = ( partState. frameSource. seek ( timestamp: i == 0 ? timestamp : partSeekOffset)
746752 |> deliverOn ( self . queue) ) . startStrict ( next: { [ weak self, weak partState] result in
747753 guard let self, let partState else {
748754 return
@@ -921,13 +927,14 @@ private final class ChunkMediaPlayerContext {
921927
922928 for partState in self . loadedState. partStates {
923929 if let audioTrackFrameBuffer = partState. mediaBuffers? . audioBuffer {
930+ //print("Poll audio: part \(partState.part.startTime) frames: \(audioTrackFrameBuffer.frames.map(\.pts.seconds))")
924931 let frame = audioTrackFrameBuffer. takeFrame ( )
925932 switch frame {
926933 case . finished:
927934 continue
928935 default :
929936 /*if case let .frame(frame) = frame {
930- print("audio: \(frame.position.seconds) \(frame.position.value) next: (\(frame.position.value + frame.duration.value))")
937+ print("audio: \(frame.position.seconds) \(frame.position.value) part \(partState.part.startTime) next: (\(frame.position.value + frame.duration.value))")
931938 }*/
932939 return frame
933940 }
0 commit comments