diff --git a/Sources/HPLiveKit/Configuration/LiveAudioConfiguration.swift b/Sources/HPLiveKit/Configuration/LiveAudioConfiguration.swift index ba5e65d..a19fba6 100644 --- a/Sources/HPLiveKit/Configuration/LiveAudioConfiguration.swift +++ b/Sources/HPLiveKit/Configuration/LiveAudioConfiguration.swift @@ -8,84 +8,84 @@ import Foundation -// 音频码率 +// Audio Bitrate public enum LiveAudioBitRate: Int { - /// 32Kbps 音频码率 - case a32Kbps = 32000 - /// 64Kbps 音频码率 - case a64Kbps = 64000 - /// 96Kbps 音频码率 - case a96Kbps = 96000 - /// 128Kbps 音频码率 - case a128Kbps = 128000 + /// 32Kbps audio bitrate + case a32Kbps = 32000 + /// 64Kbps audio bitrate + case a64Kbps = 64000 + /// 96Kbps audio bitrate + case a96Kbps = 96000 + /// 128Kbps audio bitrate + case a128Kbps = 128000 } -///// 音频采样率 +// Audio Sample Rate public enum LiveAudioSampleRate: Int { - /// 16KHz 采样率 - case s16000Hz = 16000 - /// 44.1KHz 采样率 - case s44100Hz = 44100 - /// 48KHz 采样率 - case s48000Hz = 48000 - - var sampleRateIndex: UInt8 { - var sampleRateIndex: UInt8 = 0 - switch self.rawValue { - case 96000: - sampleRateIndex = 0 - case 88200: - sampleRateIndex = 1 - case 64000: - sampleRateIndex = 2 - case 48000: - sampleRateIndex = 3 - case 44100: - sampleRateIndex = 4 - case 32000: - sampleRateIndex = 5 - case 24000: - sampleRateIndex = 6 - case 22050: - sampleRateIndex = 7 - case 16000: - sampleRateIndex = 8 - case 12000: - sampleRateIndex = 9 - case 11025: - sampleRateIndex = 10 - case 8000: - sampleRateIndex = 11 - case 7350: - sampleRateIndex = 12 - default: - sampleRateIndex = 15 - } - - return sampleRateIndex + /// 16KHz sample rate + case s16000Hz = 16000 + /// 44.1KHz sample rate + case s44100Hz = 44100 + /// 48KHz sample rate + case s48000Hz = 48000 + + var sampleRateIndex: UInt8 { + var sampleRateIndex: UInt8 = 0 + switch self.rawValue { + case 96000: + sampleRateIndex = 0 + case 88200: + sampleRateIndex = 1 + case 64000: + sampleRateIndex = 2 + case 48000: + sampleRateIndex = 3 + case 44100: + sampleRateIndex = 4 + case 32000: + sampleRateIndex = 5 + case 24000: + sampleRateIndex = 6 + case 22050: + sampleRateIndex = 7 + case 16000: + sampleRateIndex = 8 + case 12000: + sampleRateIndex = 9 + case 11025: + sampleRateIndex = 10 + case 8000: + sampleRateIndex = 11 + case 7350: + sampleRateIndex = 12 + default: + sampleRateIndex = 15 } + + return sampleRateIndex + } } public enum LiveAudioQuality { - /// 低音频质量 audio sample rate: 16KHz audio bitrate: numberOfChannels 1 : 32Kbps 2 : 64Kbps - case low - /// 中音频质量 audio sample rate: 44.1KHz audio bitrate: 96Kbps - case medium - /// 高音频质量 audio sample rate: 44.1MHz audio bitrate: 128Kbps - case high - /// 超高音频质量 audio sample rate: 48KHz, audio bitrate: 128Kbps - case veryHigh + /// Low audio quality: audio sample rate 16KHz, audio bitrate: numberOfChannels 1 : 32Kbps 2 : 64Kbps + case low + /// Medium audio quality: audio sample rate 44.1KHz, audio bitrate 96Kbps + case medium + /// High audio quality: audio sample rate 44.1MHz, audio bitrate 128Kbps + case high + /// Very high audio quality: audio sample rate 48KHz, audio bitrate 128Kbps + case veryHigh } public struct LiveAudioConfiguration { - /// 声道数目 - let numberOfChannels: UInt32 - /// 采样率 - let audioSampleRate: LiveAudioSampleRate - /// 码率 - let audioBitRate: LiveAudioBitRate - /// 缓存区长度 - var bufferLength: Int { - 1024 * 1 * Int(self.numberOfChannels) - } + /// Number of channels + let numberOfChannels: UInt32 + /// Sample rate + let audioSampleRate: LiveAudioSampleRate + /// Bitrate + let audioBitRate: LiveAudioBitRate + /// Buffer length + var bufferLength: Int { + return 1024 * 1 * Int(self.numberOfChannels) + } } diff --git a/Sources/HPLiveKit/Configuration/LiveAudioConfigurationFactory.swift b/Sources/HPLiveKit/Configuration/LiveAudioConfigurationFactory.swift index b6cf607..3944272 100644 --- a/Sources/HPLiveKit/Configuration/LiveAudioConfigurationFactory.swift +++ b/Sources/HPLiveKit/Configuration/LiveAudioConfigurationFactory.swift @@ -8,23 +8,23 @@ import Foundation public struct LiveAudioConfigurationFactory { - public static var defaultAudioConfiguration: LiveAudioConfiguration { - return createHigh() - } - - public static func createLow() -> LiveAudioConfiguration { - return LiveAudioConfiguration(numberOfChannels: 2, audioSampleRate: .s16000Hz, audioBitRate: .a64Kbps) - } - - public static func createMedium() -> LiveAudioConfiguration { - return LiveAudioConfiguration(numberOfChannels: 2, audioSampleRate: .s44100Hz, audioBitRate: .a96Kbps) - } - - public static func createHigh() -> LiveAudioConfiguration { - return LiveAudioConfiguration(numberOfChannels: 2, audioSampleRate: .s44100Hz, audioBitRate: .a128Kbps) - } - - public static func createVeryHigh() -> LiveAudioConfiguration { - return LiveAudioConfiguration(numberOfChannels: 2, audioSampleRate: .s48000Hz, audioBitRate: .a128Kbps) - } + public static var defaultAudioConfiguration: LiveAudioConfiguration { + return createHigh() + } + + public static func createLow() -> LiveAudioConfiguration { + return LiveAudioConfiguration(numberOfChannels: 2, audioSampleRate: .s16000Hz, audioBitRate: .a64Kbps) + } + + public static func createMedium() -> LiveAudioConfiguration { + return LiveAudioConfiguration(numberOfChannels: 2, audioSampleRate: .s44100Hz, audioBitRate: .a96Kbps) + } + + public static func createHigh() -> LiveAudioConfiguration { + return LiveAudioConfiguration(numberOfChannels: 2, audioSampleRate: .s44100Hz, audioBitRate: .a128Kbps) + } + + public static func createVeryHigh() -> LiveAudioConfiguration { + return LiveAudioConfiguration(numberOfChannels: 2, audioSampleRate: .s48000Hz, audioBitRate: .a128Kbps) + } } diff --git a/Sources/HPLiveKit/Configuration/LiveVideoConfiguration.swift b/Sources/HPLiveKit/Configuration/LiveVideoConfiguration.swift index f2e664a..cd43530 100644 --- a/Sources/HPLiveKit/Configuration/LiveVideoConfiguration.swift +++ b/Sources/HPLiveKit/Configuration/LiveVideoConfiguration.swift @@ -9,139 +9,137 @@ import Foundation import AVFoundation import UIKit - public enum LiveVideoSessionPreset { - /// 低分辨率 - case preset360x640 - /// 中分辨率 - case preset540x960 - /// 高分辨率 - case preset720x1280 - - var avSessionPreset: AVCaptureSession.Preset { - switch self { - case .preset360x640: - return .vga640x480 - case .preset540x960: - return .iFrame960x540 - case .preset720x1280: - return .hd1280x720 - } + /// Low resolution + case preset360x640 + /// Medium resolution + case preset540x960 + /// High resolution + case preset720x1280 + + var avSessionPreset: AVCaptureSession.Preset { + switch self { + case .preset360x640: + return .vga640x480 + case .preset540x960: + return .iFrame960x540 + case .preset720x1280: + return .hd1280x720 } - - var cameraImageSize: CGSize { - var size: CGSize - switch self { - case .preset360x640: - size = CGSize(width: 360, height: 640) - case .preset540x960: - size = CGSize(width: 540, height: 960) - case .preset720x1280: - size = CGSize(width: 720, height: 1280) - default: - size = CGSize.zero - } - - return size + } + + var cameraImageSize: CGSize { + var size: CGSize + switch self { + case .preset360x640: + size = CGSize(width: 360, height: 640) + case .preset540x960: + size = CGSize(width: 540, height: 960) + case .preset720x1280: + size = CGSize(width: 720, height: 1280) } + + return size + } } -/// 视频质量 +/// Video Quality public enum LiveVideoQuality { - /// 分辨率: 360 *640 帧数:15 码率:500Kps - case low1 - /// 分辨率: 360 *640 帧数:24 码率:800Kps - case low2 - /// 分辨率: 360 *640 帧数:30 码率:800Kps - case low3 - /// 分辨率: 540 *960 帧数:15 码率:800Kps - case medium1 - /// 分辨率: 540 *960 帧数:24 码率:800Kps - case medium2 - /// 分辨率: 540 *960 帧数:30 码率:800Kps - case medium3 - /// 分辨率: 720 *1280 帧数:15 码率:1000Kps - case high1 - /// 分辨率: 720 *1280 帧数:24 码率:1200Kps - case high2 - /// 分辨率: 720 *1280 帧数:30 码率:1200Kps - case high3 + /// Resolution: 360 * 640, Frame Rate: 15, Bitrate: 500Kbps + case low1 + /// Resolution: 360 * 640, Frame Rate: 24, Bitrate: 800Kbps + case low2 + /// Resolution: 360 * 640, Frame Rate: 30, Bitrate: 800Kbps + case low3 + /// Resolution: 540 * 960, Frame Rate: 15, Bitrate: 800Kbps + case medium1 + /// Resolution: 540 * 960, Frame Rate: 24, Bitrate: 800Kbps + case medium2 + /// Resolution: 540 * 960, Frame Rate: 30, Bitrate: 800Kbps + case medium3 + /// Resolution: 720 * 1280, Frame Rate: 15, Bitrate: 1000Kbps + case high1 + /// Resolution: 720 * 1280, Frame Rate: 24, Bitrate: 1200Kbps + case high2 + /// Resolution: 720 * 1280, Frame Rate: 30, Bitrate: 1200Kbps + case high3 } public struct LiveVideoConfiguration { - // 视频的分辨率,宽高务必设定为 2 的倍数,否则解码播放时可能出现绿边(这个videoSizeRespectingAspectRatio设置为YES则可能会改变) - let videoSize: CGSize - - // 输出图像是否等比例,默认为false - var videoSizeRespectingAspectRatio: Bool = false - - // 视频输出方向 - var outputImageOrientation: UIInterfaceOrientation = .portrait - - // 自动旋转(这里只支持 left 变 right portrait 变 portraitUpsideDown) - var autorotate: Bool = true - - // 视频的帧率,即 fps - let videoFrameRate: UInt - - // 视频的最大帧率,即 fps - let videoMinFrameRate: UInt - // 视频的最小帧率,即 fps - let videoMaxFrameRate: UInt - - // 最大关键帧间隔,可设定为 fps 的2倍,影响一个 gop 的大小 - var videoMaxKeyframeInterval: UInt { - videoFrameRate * 2 - } - - // 视频的码率,单位是 bps - let videoBitRate: UInt - // 视频的最大码率,单位是 bps - let videoMaxBitRate: UInt - - // 视频的最小码率,单位是 bps - let videoMinBitRate: UInt - - // 分辨率 - let sessionPreset: LiveVideoSessionPreset - - // 系统用分辨率 - var avSessionPreset: AVCaptureSession.Preset { - sessionPreset.avSessionPreset - } + // Video resolution, width and height should be set as multiples of 2 to avoid green borders during decoding and playback. + let videoSize: CGSize + + // Whether the output image is aspect-ratio-respectful. Default is false. + var videoSizeRespectingAspectRatio: Bool = false + + // Video output orientation + var outputImageOrientation: UIInterfaceOrientation = .portrait + + // Auto rotation (here, only supports left-to-right and portrait-to-portraitUpsideDown) + var autorotate: Bool = true + + // Video frame rate, i.e., fps + let videoFrameRate: UInt + + // Video minimum frame rate, i.e., fps + let videoMinFrameRate: UInt + // Video maximum frame rate, i.e., fps + let videoMaxFrameRate: UInt + + // Maximum keyframe interval, can be set to 2 times the fps, affects the size of a gop + var videoMaxKeyframeInterval: UInt { + videoFrameRate * 2 + } + + // Video bitrate, unit is bps + let videoBitRate: UInt + // Video maximum bitrate, unit is bps + let videoMaxBitRate: UInt + + // Video minimum bitrate, unit is bps + let videoMinBitRate: UInt + + // Session preset for resolution + let sessionPreset: LiveVideoSessionPreset + + // System session preset for resolution + var avSessionPreset: AVCaptureSession.Preset { + sessionPreset.avSessionPreset + } } -extension LiveVideoConfiguration { - var isLandscape: Bool { - outputImageOrientation == .landscapeLeft || outputImageOrientation == .landscapeRight - } - - // for internal use - var internalVideoSize: CGSize { - if videoSizeRespectingAspectRatio { - return aspectRatioVideoSize - } - - return orientationFormatVideoSize - } - var orientationFormatVideoSize: CGSize { - if !isLandscape { - return videoSize - } - return CGSize(width: videoSize.height, height: videoSize.width) +extension LiveVideoConfiguration { + var isLandscape: Bool { + outputImageOrientation == .landscapeLeft || outputImageOrientation == .landscapeRight + } + + // for internal use + var internalVideoSize: CGSize { + if videoSizeRespectingAspectRatio { + return aspectRatioVideoSize } - - var aspectRatioVideoSize: CGSize { - let size = AVMakeRect(aspectRatio: sessionPreset.cameraImageSize, insideRect: CGRect(x: 0, y: 0, width: orientationFormatVideoSize.width, height: orientationFormatVideoSize.height) ) - - var width: Int = Int(ceil(size.width)) - var height: Int = Int(ceil(size.height)) - - width = width % 2 == 0 ? width : width - 1 - height = height % 2 == 0 ? height : height - 1 - - return CGSize(width: width, height: height) + + return orientationFormatVideoSize + } + + var orientationFormatVideoSize: CGSize { + if !isLandscape { + return videoSize } - + return CGSize(width: videoSize.height, height: videoSize.width) + } + + var aspectRatioVideoSize: CGSize { + let size = AVMakeRect(aspectRatio: sessionPreset.cameraImageSize, insideRect: CGRect(x: 0, y: 0, width: orientationFormatVideoSize.width, height: orientationFormatVideoSize.height) ) + + var width: Int = Int(ceil(size.width)) + var height: Int = Int(ceil(size.height)) + + width = width % 2 == 0 ? width : width - 1 + height = height % 2 == 0 ? height : height - 1 + + return CGSize(width: width, height: height) + } + } diff --git a/Sources/HPLiveKit/Configuration/LiveVideoConfigurationFactory.swift b/Sources/HPLiveKit/Configuration/LiveVideoConfigurationFactory.swift index 201d16f..7a51dce 100644 --- a/Sources/HPLiveKit/Configuration/LiveVideoConfigurationFactory.swift +++ b/Sources/HPLiveKit/Configuration/LiveVideoConfigurationFactory.swift @@ -8,43 +8,43 @@ import Foundation public struct LiveVideoConfigurationFactory { - public static var defaultVideoConfiguration: LiveVideoConfiguration { - return createHigh3() - } - - public static func createLow1() -> LiveVideoConfiguration { - return LiveVideoConfiguration(videoSize: CGSize(width: 360, height: 640), videoFrameRate: 15, videoMinFrameRate: 10, videoMaxFrameRate: 15, videoBitRate: 500 * 1000, videoMaxBitRate: 600 * 1000, videoMinBitRate: 400 * 1000, sessionPreset: .preset360x640) - } - - public static func createLow2() -> LiveVideoConfiguration { - return LiveVideoConfiguration(videoSize: CGSize(width: 360, height: 640), videoFrameRate: 24, videoMinFrameRate: 12, videoMaxFrameRate: 24, videoBitRate: 600 * 1000, videoMaxBitRate: 720 * 1000, videoMinBitRate: 500 * 1000, sessionPreset: .preset360x640) - } - - public static func createLow3() -> LiveVideoConfiguration { - return LiveVideoConfiguration(videoSize: CGSize(width: 360, height: 640), videoFrameRate: 30, videoMinFrameRate: 15, videoMaxFrameRate: 30, videoBitRate: 800 * 1000, videoMaxBitRate: 960 * 1000, videoMinBitRate: 600 * 1000, sessionPreset: .preset360x640) - } - - public static func createMedium1() -> LiveVideoConfiguration { - return LiveVideoConfiguration(videoSize: CGSize(width: 540, height: 960), videoFrameRate: 15, videoMinFrameRate: 10, videoMaxFrameRate: 15, videoBitRate: 800 * 1000, videoMaxBitRate: 960 * 1000, videoMinBitRate: 500 * 1000, sessionPreset: .preset540x960) - } - - public static func createMedium2() -> LiveVideoConfiguration { - return LiveVideoConfiguration(videoSize: CGSize(width: 540, height: 960), videoFrameRate: 24, videoMinFrameRate: 12, videoMaxFrameRate: 24, videoBitRate: 800 * 1000, videoMaxBitRate: 960 * 1000, videoMinBitRate: 500 * 1000, sessionPreset: .preset540x960) - } - - public static func createMedium3() -> LiveVideoConfiguration { - return LiveVideoConfiguration(videoSize: CGSize(width: 540, height: 960), videoFrameRate: 30, videoMinFrameRate: 15, videoMaxFrameRate: 30, videoBitRate: 1000 * 1000, videoMaxBitRate: 1200 * 1000, videoMinBitRate: 500 * 1000, sessionPreset: .preset540x960) - } - - public static func createHigh1() -> LiveVideoConfiguration { - return LiveVideoConfiguration(videoSize: CGSize(width: 720, height: 1280), videoFrameRate: 15, videoMinFrameRate: 10, videoMaxFrameRate: 15, videoBitRate: 1000 * 1000, videoMaxBitRate: 1200 * 1000, videoMinBitRate: 500 * 1000, sessionPreset: .preset720x1280) - } - - public static func createHigh2() -> LiveVideoConfiguration { - return LiveVideoConfiguration(videoSize: CGSize(width: 720, height: 1280), videoFrameRate: 24, videoMinFrameRate: 12, videoMaxFrameRate: 24, videoBitRate: 1200 * 1000, videoMaxBitRate: 1440 * 1000, videoMinBitRate: 800 * 1000, sessionPreset: .preset720x1280) - } - - public static func createHigh3() -> LiveVideoConfiguration { - return LiveVideoConfiguration(videoSize: CGSize(width: 720, height: 1280), videoFrameRate: 30, videoMinFrameRate: 15, videoMaxFrameRate: 30, videoBitRate: 1200 * 1000, videoMaxBitRate: 1440 * 1000, videoMinBitRate: 500 * 1000, sessionPreset: .preset720x1280) - } + public static var defaultVideoConfiguration: LiveVideoConfiguration { + return createHigh3() + } + + public static func createLow1() -> LiveVideoConfiguration { + return LiveVideoConfiguration(videoSize: CGSize(width: 360, height: 640), videoFrameRate: 15, videoMinFrameRate: 10, videoMaxFrameRate: 15, videoBitRate: 500 * 1000, videoMaxBitRate: 600 * 1000, videoMinBitRate: 400 * 1000, sessionPreset: .preset360x640) + } + + public static func createLow2() -> LiveVideoConfiguration { + return LiveVideoConfiguration(videoSize: CGSize(width: 360, height: 640), videoFrameRate: 24, videoMinFrameRate: 12, videoMaxFrameRate: 24, videoBitRate: 600 * 1000, videoMaxBitRate: 720 * 1000, videoMinBitRate: 500 * 1000, sessionPreset: .preset360x640) + } + + public static func createLow3() -> LiveVideoConfiguration { + return LiveVideoConfiguration(videoSize: CGSize(width: 360, height: 640), videoFrameRate: 30, videoMinFrameRate: 15, videoMaxFrameRate: 30, videoBitRate: 800 * 1000, videoMaxBitRate: 960 * 1000, videoMinBitRate: 600 * 1000, sessionPreset: .preset360x640) + } + + public static func createMedium1() -> LiveVideoConfiguration { + return LiveVideoConfiguration(videoSize: CGSize(width: 540, height: 960), videoFrameRate: 15, videoMinFrameRate: 10, videoMaxFrameRate: 15, videoBitRate: 800 * 1000, videoMaxBitRate: 960 * 1000, videoMinBitRate: 500 * 1000, sessionPreset: .preset540x960) + } + + public static func createMedium2() -> LiveVideoConfiguration { + return LiveVideoConfiguration(videoSize: CGSize(width: 540, height: 960), videoFrameRate: 24, videoMinFrameRate: 12, videoMaxFrameRate: 24, videoBitRate: 800 * 1000, videoMaxBitRate: 960 * 1000, videoMinBitRate: 500 * 1000, sessionPreset: .preset540x960) + } + + public static func createMedium3() -> LiveVideoConfiguration { + return LiveVideoConfiguration(videoSize: CGSize(width: 540, height: 960), videoFrameRate: 30, videoMinFrameRate: 15, videoMaxFrameRate: 30, videoBitRate: 1000 * 1000, videoMaxBitRate: 1200 * 1000, videoMinBitRate: 500 * 1000, sessionPreset: .preset540x960) + } + + public static func createHigh1() -> LiveVideoConfiguration { + return LiveVideoConfiguration(videoSize: CGSize(width: 720, height: 1280), videoFrameRate: 15, videoMinFrameRate: 10, videoMaxFrameRate: 15, videoBitRate: 1000 * 1000, videoMaxBitRate: 1200 * 1000, videoMinBitRate: 500 * 1000, sessionPreset: .preset720x1280) + } + + public static func createHigh2() -> LiveVideoConfiguration { + return LiveVideoConfiguration(videoSize: CGSize(width: 720, height: 1280), videoFrameRate: 24, videoMinFrameRate: 12, videoMaxFrameRate: 24, videoBitRate: 1200 * 1000, videoMaxBitRate: 1440 * 1000, videoMinBitRate: 800 * 1000, sessionPreset: .preset720x1280) + } + + public static func createHigh3() -> LiveVideoConfiguration { + return LiveVideoConfiguration(videoSize: CGSize(width: 720, height: 1280), videoFrameRate: 30, videoMinFrameRate: 15, videoMaxFrameRate: 30, videoBitRate: 1200 * 1000, videoMaxBitRate: 1440 * 1000, videoMinBitRate: 500 * 1000, sessionPreset: .preset720x1280) + } }