Skip to content

Commit

Permalink
优化直播时延算法 #525
Browse files Browse the repository at this point in the history
  • Loading branch information
kingslay committed Oct 31, 2023
1 parent 5fffa26 commit 19c8e67
Show file tree
Hide file tree
Showing 8 changed files with 405 additions and 49 deletions.
57 changes: 35 additions & 22 deletions Sources/KSPlayer/AVPlayer/KSOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -157,19 +157,15 @@ open class KSOptions {

// 缓冲算法函数
open func playable(capacitys: [CapacityProtocol], isFirst: Bool, isSeek: Bool) -> LoadingState {
let packetCount = capacitys.map(\.packetCount).max() ?? 0
let frameCount = capacitys.map(\.frameCount).max() ?? 0
let packetCount = capacitys.map(\.packetCount).min() ?? 0
let frameCount = capacitys.map(\.frameCount).min() ?? 0
let isEndOfFile = capacitys.allSatisfy(\.isEndOfFile)
let loadedTime = capacitys.map(\.loadedTime).min() ?? 0
let progress = loadedTime * 100.0 / preferredForwardBufferDuration
let isPlayable = capacitys.allSatisfy { capacity in
if capacity.isEndOfFile && capacity.packetCount == 0 {
return true
}
// 处理视频轨道一致没有值的问题(纯音频)
if capacitys.count > 1, capacity.mediaType == .video && capacity.frameCount == 0 && capacity.packetCount == 0 {
return true
}
guard capacity.frameCount >= capacity.frameMaxCount >> 2 else {
return false
}
Expand All @@ -184,8 +180,8 @@ open class KSOptions {
if capacity.mediaType == .audio || isSecondOpen {
if isFirst {
return true
} else if isSeek, capacity.packetCount >= Int(capacity.fps) {
return true
} else {
return capacity.loadedTime >= preferredForwardBufferDuration / 2
}
}
}
Expand Down Expand Up @@ -344,7 +340,7 @@ open class KSOptions {
}

// private var lastMediaTime = CACurrentMediaTime()
open func videoClockSync(main: KSClock, nextVideoTime: TimeInterval, fps: Float) -> ClockProcessType {
open func videoClockSync(main: KSClock, nextVideoTime: TimeInterval, fps: Float, frameCount: Int) -> ClockProcessType {
var desire = main.getTime() - videoDelay
#if !os(macOS)
desire -= AVAudioSession.sharedInstance().outputLatency
Expand All @@ -358,19 +354,33 @@ open class KSOptions {
return .remain
} else {
if diff < -4 / Double(fps) {
KSLog("[video] video delay=\(diff), clock=\(desire), delay count=\(videoClockDelayCount)")
videoClockDelayCount += 1
if diff < -8, videoClockDelayCount % 100 == 0 {
KSLog("[video] video delay seek video track")
return .seek
}
if diff < -1, videoClockDelayCount % 10 == 0 {
return .flush
}
if videoClockDelayCount % 2 == 0 {
return .dropNext
let log = "[video] video delay=\(diff), clock=\(desire), delay count=\(videoClockDelayCount), frameCount=\(frameCount)"
if frameCount == 1 {
if diff < -1, videoClockDelayCount % 10 == 0 {
KSLog("\(log) drop gop Packet")
return .dropGOPPacket
} else if videoClockDelayCount % 5 == 0 {
KSLog("\(log) drop next frame")
return .dropNextFrame
} else {
return .next
}
} else {
return .next
if diff < -8, videoClockDelayCount % 100 == 0 {
KSLog("\(log) seek video track")
return .seek
}
if diff < -1, videoClockDelayCount % 10 == 0 {
KSLog("\(log) flush video track")
return .flush
}
if videoClockDelayCount % 2 == 0 {
KSLog("\(log) drop next frame")
return .dropNextFrame
} else {
return .next
}
}
} else {
videoClockDelayCount = 0
Expand Down Expand Up @@ -409,9 +419,12 @@ open class KSOptions {
}

open func liveAdaptivePlaybackRate(loadingState: LoadingState) -> Float? {
if loadingState.loadedTime > preferredForwardBufferDuration + 4 {
if loadingState.isFirst {
return nil
}
if loadingState.loadedTime > preferredForwardBufferDuration + 5 {
return 1.2
} else if loadingState.loadedTime < preferredForwardBufferDuration {
} else if loadingState.loadedTime < preferredForwardBufferDuration / 2 {
return 0.8
} else {
return 1
Expand Down
4 changes: 3 additions & 1 deletion Sources/KSPlayer/AVPlayer/PlayerDefines.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,9 @@ public struct VideoAdaptationState {
public enum ClockProcessType {
case remain
case next
case dropNext
case dropNextFrame
case dropNextPacket
case dropGOPPacket
case flush
case seek
}
Expand Down
Loading

0 comments on commit 19c8e67

Please sign in to comment.