Relocate the nested type is defined.

This commit is contained in:
shogo4405 2023-05-03 15:54:10 +09:00
parent fdc9aa3272
commit f7f6ee42b0
9 changed files with 163 additions and 172 deletions

View File

@ -70,9 +70,6 @@
2955F51F1D09EBAD004CC995 /* VisualEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296897461CDB01D20074D5F0 /* VisualEffect.swift */; };
29562B881E6BFFE000BB940A /* HaishinKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 29B8761B1CD701F900FC07DA /* HaishinKit.framework */; };
29562B891E6BFFE000BB940A /* HaishinKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 29B8761B1CD701F900FC07DA /* HaishinKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
295891011EEB7A8B00CE51E1 /* ScalingMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 295891001EEB7A8B00CE51E1 /* ScalingMode.swift */; };
295891021EEB7AFC00CE51E1 /* ScalingMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 295891001EEB7A8B00CE51E1 /* ScalingMode.swift */; };
295891031EEB7AFC00CE51E1 /* ScalingMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 295891001EEB7A8B00CE51E1 /* ScalingMode.swift */; };
2958910A1EEB8D1800CE51E1 /* FLVReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 295891091EEB8D1800CE51E1 /* FLVReader.swift */; };
2958910B1EEB8D1800CE51E1 /* FLVReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 295891091EEB8D1800CE51E1 /* FLVReader.swift */; };
2958910C1EEB8D1800CE51E1 /* FLVReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 295891091EEB8D1800CE51E1 /* FLVReader.swift */; };
@ -121,9 +118,6 @@
29798E751CE614FE00F5CBD0 /* SampleVideo_360x240_5mb in Resources */ = {isa = PBXBuildFile; fileRef = 29B876D71CD70CE700FC07DA /* SampleVideo_360x240_5mb */; };
29798E761CE614FE00F5CBD0 /* SampleVideo_360x240_5mb.m3u8 in Resources */ = {isa = PBXBuildFile; fileRef = 29B876D81CD70CE700FC07DA /* SampleVideo_360x240_5mb.m3u8 */; };
29798E771CE614FE00F5CBD0 /* SampleVideo_360x240_5mb.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 29B876D91CD70CE700FC07DA /* SampleVideo_360x240_5mb.mp4 */; };
297E69122324E38800D418AB /* AudioCodecFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 297E69112324E38800D418AB /* AudioCodecFormat.swift */; };
297E69132324E38800D418AB /* AudioCodecFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 297E69112324E38800D418AB /* AudioCodecFormat.swift */; };
297E69142324E38800D418AB /* AudioCodecFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 297E69112324E38800D418AB /* AudioCodecFormat.swift */; };
298BCF331DD4C44A007FF86A /* AnyUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 298BCF321DD4C44A007FF86A /* AnyUtil.swift */; };
2999C3752071138F00892E55 /* MTHKView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2999C3742071138F00892E55 /* MTHKView.swift */; };
299B13271D3B751400A1E8F5 /* HKView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 299B13261D3B751400A1E8F5 /* HKView.swift */; };
@ -621,7 +615,6 @@
2950181F1FFA1BD700358E10 /* AudioCodecTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioCodecTests.swift; sourceTree = "<group>"; };
295018211FFA1C9D00358E10 /* SinWaveUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SinWaveUtil.swift; sourceTree = "<group>"; };
2950742E1E4620B7007F15A4 /* PreferenceViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferenceViewController.swift; sourceTree = "<group>"; };
295891001EEB7A8B00CE51E1 /* ScalingMode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScalingMode.swift; sourceTree = "<group>"; };
295891091EEB8D1800CE51E1 /* FLVReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FLVReader.swift; sourceTree = "<group>"; };
2958910D1EEB8D3C00CE51E1 /* FLVVideoCodec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FLVVideoCodec.swift; sourceTree = "<group>"; };
295891111EEB8D7200CE51E1 /* FLVFrameType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FLVFrameType.swift; sourceTree = "<group>"; };
@ -653,7 +646,6 @@
2976A4851D4903C300B53EF2 /* DeviceUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceUtil.swift; sourceTree = "<group>"; };
29798E591CE60E5300F5CBD0 /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
29798E5D1CE60E5300F5CBD0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
297E69112324E38800D418AB /* AudioCodecFormat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioCodecFormat.swift; sourceTree = "<group>"; };
2981E1301D646E3F00E8F7CA /* Cartfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Cartfile; sourceTree = "<group>"; };
298BCF321DD4C44A007FF86A /* AnyUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyUtil.swift; sourceTree = "<group>"; };
2997BDD31D50D31B000AF900 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
@ -899,7 +891,6 @@
isa = PBXGroup;
children = (
29B876571CD70A7900FC07DA /* AudioCodec.swift */,
297E69112324E38800D418AB /* AudioCodecFormat.swift */,
BC44A1A823D31E92002D4297 /* AudioCodecRingBuffer.swift */,
BC7C56B6299E579F00C41A9B /* AudioCodecSettings.swift */,
29B876591CD70A7900FC07DA /* VideoCodec.swift */,
@ -1238,7 +1229,6 @@
2999C3742071138F00892E55 /* MTHKView.swift */,
BC110256292E661E00D48035 /* MultiCamCaptureSettings.swift */,
BC34FA0A286CB90A00EFAF27 /* PiPHKView.swift */,
295891001EEB7A8B00CE51E1 /* ScalingMode.swift */,
BC3004CD296B0A1700119932 /* Shape.swift */,
BC6FC91D29609A6800A746EE /* ShapeFactory.swift */,
29B8768D1CD70AFE00FC07DA /* SoundTransform.swift */,
@ -1881,7 +1871,6 @@
29B876B11CD70B2800FC07DA /* RTMPMessage.swift in Sources */,
2941746B22D069B300A2944F /* AudioEffect.swift in Sources */,
BCB9773F2621812800C9A649 /* AVCFormatStream.swift in Sources */,
295891011EEB7A8B00CE51E1 /* ScalingMode.swift in Sources */,
BC83A4732403D83B006BDE06 /* VTCompressionSession+Extension.swift in Sources */,
BC4914A228DDD33D009E2DF6 /* VTSessionConvertible.swift in Sources */,
2915EC4D1D85BB8C00621092 /* RTMPTSocket.swift in Sources */,
@ -1947,7 +1936,6 @@
29B876AB1CD70B2800FC07DA /* AMF0Serializer.swift in Sources */,
29B8765B1CD70A7900FC07DA /* AudioCodec.swift in Sources */,
29EA87D51E799F670043A5F8 /* Mirror+Extension.swift in Sources */,
297E69122324E38800D418AB /* AudioCodecFormat.swift in Sources */,
2942A4F821A9418A004E1BEE /* Running.swift in Sources */,
29F6F4851DFB83E200920A3A /* RTMPHandshake.swift in Sources */,
29EA87DF1E79A0810043A5F8 /* CMSampleBuffer+Extension.swift in Sources */,
@ -2058,7 +2046,6 @@
BC110254292DD6E900D48035 /* vImage_Buffer+Extension.swift in Sources */,
29EA87D61E799F6A0043A5F8 /* Mirror+Extension.swift in Sources */,
BC7A23F525171C8F0089F77C /* MTHKView.swift in Sources */,
297E69132324E38800D418AB /* AudioCodecFormat.swift in Sources */,
29B876F81CD70D5900FC07DA /* HTTPService.swift in Sources */,
29B876F91CD70D5900FC07DA /* HTTPStream.swift in Sources */,
296543631D62FE9000734698 /* HKView-macOS.swift in Sources */,
@ -2129,7 +2116,6 @@
BC6FC9232961B3D800A746EE /* vImage_CGImageFormat+Extension.swift in Sources */,
29B877131CD70D5A00FC07DA /* RTMPConnection.swift in Sources */,
2958910F1EEB8D3C00CE51E1 /* FLVVideoCodec.swift in Sources */,
295891021EEB7AFC00CE51E1 /* ScalingMode.swift in Sources */,
29B877141CD70D5A00FC07DA /* RTMPMessage.swift in Sources */,
29B877151CD70D5A00FC07DA /* RTMPMuxer.swift in Sources */,
29EA87E31E79A1E90043A5F8 /* CMVideoFormatDescription+Extension.swift in Sources */,
@ -2237,7 +2223,6 @@
29EB3E0D1ED05877001CAE8B /* IOAudioUnit.swift in Sources */,
2942A4FA21A9418A004E1BEE /* Running.swift in Sources */,
295891101EEB8D3C00CE51E1 /* FLVVideoCodec.swift in Sources */,
295891031EEB7AFC00CE51E1 /* ScalingMode.swift in Sources */,
29EB3DFD1ED05847001CAE8B /* CVPixelBuffer+Extension.swift in Sources */,
BCC1A72D264FAC1800661156 /* ESSpecificData.swift in Sources */,
BCB976E126107B5600C9A649 /* TSField.swift in Sources */,
@ -2253,7 +2238,6 @@
29DF20682312A436004057C3 /* RTMPSocketCompatible.swift in Sources */,
29EB3E0B1ED05871001CAE8B /* TSReader.swift in Sources */,
BC7C56BD299E595000C41A9B /* VideoCodecSettings.swift in Sources */,
297E69142324E38800D418AB /* AudioCodecFormat.swift in Sources */,
29EB3DF51ED05779001CAE8B /* CMFormatDescription+Extension.swift in Sources */,
BC110255292DD6E900D48035 /* vImage_Buffer+Extension.swift in Sources */,
BC570B4A28E9ACC10098A12C /* IOUnit.swift in Sources */,

View File

@ -23,8 +23,7 @@ public class AudioCodec {
case failedToCreate(from: AVAudioFormat, to: AVAudioFormat)
case failedToConvert(error: NSError)
}
/// Specifies the output format.
public var destination: AudioCodecFormat = .aac
/// Specifies the delegate.
public weak var delegate: AudioCodecDelegate?
/// This instance is running to process(true) or not(false).
@ -56,7 +55,7 @@ public class AudioCodec {
guard isRunning.value else {
return
}
switch destination {
switch settings.format {
case .aac:
guard let audioConverter, let ringBuffer else {
return
@ -143,7 +142,7 @@ public class AudioCodec {
return nil
}
if outputBuffers.isEmpty {
return destination.makeAudioBuffer(outputFormat)
return settings.format.makeAudioBuffer(outputFormat)
}
return outputBuffers.removeFirst()
}
@ -151,7 +150,7 @@ public class AudioCodec {
private func makeAudioConverter(_ inSourceFormat: inout AudioStreamBasicDescription) -> AVAudioConverter? {
guard
let inputFormat = AVAudioFormat(streamDescription: &inSourceFormat),
let outputFormat = destination.makeAudioFormat(inSourceFormat) else {
let outputFormat = settings.format.makeAudioFormat(inSourceFormat) else {
return nil
}
let converter = AVAudioConverter(from: inputFormat, to: outputFormat)

View File

@ -1,110 +0,0 @@
import AudioToolbox
import AVFoundation
/// The type of the AudioCodec supports format.
public enum AudioCodecFormat {
/// The AAC format.
case aac
/// The PCM format.
case pcm
var formatID: AudioFormatID {
switch self {
case .aac:
return kAudioFormatMPEG4AAC
case .pcm:
return kAudioFormatLinearPCM
}
}
var formatFlags: UInt32 {
switch self {
case .aac:
return UInt32(MPEG4ObjectID.AAC_LC.rawValue)
case .pcm:
return kAudioFormatFlagIsNonInterleaved | kAudioFormatFlagIsPacked | kAudioFormatFlagIsFloat
}
}
var framesPerPacket: UInt32 {
switch self {
case .aac:
return 1024
case .pcm:
return 1
}
}
var packetSize: UInt32 {
switch self {
case .aac:
return 1
case .pcm:
return 1024
}
}
var bitsPerChannel: UInt32 {
switch self {
case .aac:
return 0
case .pcm:
return 32
}
}
var bytesPerPacket: UInt32 {
switch self {
case .aac:
return 0
case .pcm:
return (bitsPerChannel / 8)
}
}
var bytesPerFrame: UInt32 {
switch self {
case .aac:
return 0
case .pcm:
return (bitsPerChannel / 8)
}
}
func makeAudioBuffer(_ format: AVAudioFormat) -> AVAudioBuffer? {
switch self {
case .aac:
return AVAudioCompressedBuffer(format: format, packetCapacity: 1, maximumPacketSize: 1024)
case .pcm:
return AVAudioPCMBuffer(pcmFormat: format, frameCapacity: 1024)
}
}
func makeAudioFormat(_ inSourceFormat: AudioStreamBasicDescription?) -> AVAudioFormat? {
guard let inSourceFormat else {
return nil
}
switch self {
case .aac:
var streamDescription = AudioStreamBasicDescription(
mSampleRate: inSourceFormat.mSampleRate,
mFormatID: formatID,
mFormatFlags: formatFlags,
mBytesPerPacket: bytesPerPacket,
mFramesPerPacket: framesPerPacket,
mBytesPerFrame: bytesPerFrame,
mChannelsPerFrame: inSourceFormat.mChannelsPerFrame,
mBitsPerChannel: bitsPerChannel,
mReserved: 0
)
return AVAudioFormat(streamDescription: &streamDescription)
case .pcm:
return AVAudioFormat(
commonFormat: .pcmFormatFloat32,
sampleRate: inSourceFormat.mSampleRate,
channels: inSourceFormat.mChannelsPerFrame,
interleaved: true
)
}
}
}

View File

@ -6,12 +6,127 @@ public struct AudioCodecSettings: Codable {
/// The defualt value.
public static let `default` = AudioCodecSettings()
/// The type of the AudioCodec supports format.
public enum Format: Codable {
/// The AAC format.
case aac
/// The PCM format.
case pcm
var formatID: AudioFormatID {
switch self {
case .aac:
return kAudioFormatMPEG4AAC
case .pcm:
return kAudioFormatLinearPCM
}
}
var formatFlags: UInt32 {
switch self {
case .aac:
return UInt32(MPEG4ObjectID.AAC_LC.rawValue)
case .pcm:
return kAudioFormatFlagIsNonInterleaved | kAudioFormatFlagIsPacked | kAudioFormatFlagIsFloat
}
}
var framesPerPacket: UInt32 {
switch self {
case .aac:
return 1024
case .pcm:
return 1
}
}
var packetSize: UInt32 {
switch self {
case .aac:
return 1
case .pcm:
return 1024
}
}
var bitsPerChannel: UInt32 {
switch self {
case .aac:
return 0
case .pcm:
return 32
}
}
var bytesPerPacket: UInt32 {
switch self {
case .aac:
return 0
case .pcm:
return (bitsPerChannel / 8)
}
}
var bytesPerFrame: UInt32 {
switch self {
case .aac:
return 0
case .pcm:
return (bitsPerChannel / 8)
}
}
func makeAudioBuffer(_ format: AVAudioFormat) -> AVAudioBuffer? {
switch self {
case .aac:
return AVAudioCompressedBuffer(format: format, packetCapacity: 1, maximumPacketSize: 1024)
case .pcm:
return AVAudioPCMBuffer(pcmFormat: format, frameCapacity: 1024)
}
}
func makeAudioFormat(_ inSourceFormat: AudioStreamBasicDescription?) -> AVAudioFormat? {
guard let inSourceFormat else {
return nil
}
switch self {
case .aac:
var streamDescription = AudioStreamBasicDescription(
mSampleRate: inSourceFormat.mSampleRate,
mFormatID: formatID,
mFormatFlags: formatFlags,
mBytesPerPacket: bytesPerPacket,
mFramesPerPacket: framesPerPacket,
mBytesPerFrame: bytesPerFrame,
mChannelsPerFrame: inSourceFormat.mChannelsPerFrame,
mBitsPerChannel: bitsPerChannel,
mReserved: 0
)
return AVAudioFormat(streamDescription: &streamDescription)
case .pcm:
return AVAudioFormat(
commonFormat: .pcmFormatFloat32,
sampleRate: inSourceFormat.mSampleRate,
channels: inSourceFormat.mChannelsPerFrame,
interleaved: true
)
}
}
}
/// Specifies the bitRate of audio output.
public var bitRate: Int
/// Specifies the output format.
public var format: AudioCodecSettings.Format
/// Create an new AudioCodecSettings instance.
public init(bitRate: Int = 64 * 1000) {
public init(
bitRate: Int = 64 * 1000,
format: AudioCodecSettings.Format = .aac
) {
self.bitRate = bitRate
self.format = format
}
func apply(_ converter: AVAudioConverter?, oldValue: AudioCodecSettings?) {

View File

@ -35,27 +35,6 @@ public class VideoCodec {
#endif
#endif
/// A bitRate mode that affectes how to encode the video source.
public enum BitRateMode: String, Codable {
/// The average bit rate.
case average
/// The constant bit rate.
@available(iOS 16.0, tvOS 16.0, macOS 13.0, *)
case constant
var key: VTSessionOptionKey {
if #available(iOS 16.0, tvOS 16.0, macOS 13.0, *) {
switch self {
case .average:
return .averageBitRate
case .constant:
return .constantBitRate
}
}
return .averageBitRate
}
}
/**
* The VideoCodec error domain codes.
*/

View File

@ -6,6 +6,43 @@ public struct VideoCodecSettings: Codable {
/// The defulat value.
public static let `default` = VideoCodecSettings()
/// A bitRate mode that affectes how to encode the video source.
public enum BitRateMode: String, Codable {
/// The average bit rate.
case average
/// The constant bit rate.
@available(iOS 16.0, tvOS 16.0, macOS 13.0, *)
case constant
var key: VTSessionOptionKey {
if #available(iOS 16.0, tvOS 16.0, macOS 13.0, *) {
switch self {
case .average:
return .averageBitRate
case .constant:
return .constantBitRate
}
}
return .averageBitRate
}
}
/**
* The scaling mode.
* - seealso: https://developer.apple.com/documentation/videotoolbox/kvtpixeltransferpropertykey_scalingmode
* - seealso: https://developer.apple.com/documentation/videotoolbox/vtpixeltransfersession/pixel_transfer_properties/scaling_mode_constants
*/
public enum ScalingMode: String, Codable {
/// kVTScalingMode_Normal
case normal = "Normal"
/// kVTScalingMode_Letterbox
case letterbox = "Letterbox"
/// kVTScalingMode_CropSourceToCleanAperture
case cropSourceToCleanAperture = "CropSourceToCleanAperture"
/// kVTScalingMode_Trim
case trim = "Trim"
}
/// Specifies the video size of encoding video.
public var videoSize: VideoSize
/// Specifies the bitrate.
@ -18,7 +55,7 @@ public struct VideoCodecSettings: Codable {
/// Specifies the allowFrameRecording.
public var allowFrameReordering: Bool?
/// Specifies the bitRateMode.
public var bitRateMode: VideoCodec.BitRateMode
public var bitRateMode: BitRateMode
/// Specifies the H264 profileLevel.
public var profileLevel: String
/// Specifies the HardwareEncoder is enabled(TRUE), or not(FALSE) for macOS.
@ -33,7 +70,7 @@ public struct VideoCodecSettings: Codable {
bitRate: UInt32 = 640 * 1000,
maxKeyFrameIntervalDuration: Int32 = 2,
scalingMode: ScalingMode = .trim,
bitRateMode: VideoCodec.BitRateMode = .average,
bitRateMode: BitRateMode = .average,
allowFrameReordering: Bool? = nil,
isHardwareEncoderEnabled: Bool = true
) {

View File

@ -7,6 +7,7 @@ extension AVCaptureSession {
get {
false
}
// swiftlint:disable unused_setter_value
set {
logger.warn("isMultitaskingCameraAccessSupported is unavailabled in Mac Catalyst.")
}
@ -16,6 +17,7 @@ extension AVCaptureSession {
get {
false
}
// swiftlint:disable unused_setter_value
set {
logger.warn("isMultitaskingCameraAccessEnabled is unavailabled in Mac Catalyst.")
}

View File

@ -1,15 +0,0 @@
/**
* The scaling mode.
* - seealso: https://developer.apple.com/documentation/videotoolbox/kvtpixeltransferpropertykey_scalingmode
* - seealso: https://developer.apple.com/documentation/videotoolbox/vtpixeltransfersession/pixel_transfer_properties/scaling_mode_constants
*/
public enum ScalingMode: String, Codable {
/// kVTScalingMode_Normal
case normal = "Normal"
/// kVTScalingMode_Letterbox:
case letterbox = "Letterbox"
/// kVTScalingMode_CropSourceToCleanAperture
case cropSourceToCleanAperture = "CropSourceToCleanAperture"
/// kVTScalingMode_Trim
case trim = "Trim"
}

View File

@ -585,11 +585,11 @@ final class RTMPAudioMessage: RTMPMessage {
switch FLVAACPacketType(rawValue: payload[1]) {
case .seq?:
let config = AudioSpecificConfig(bytes: [UInt8](payload[codec.headerSize..<payload.count]))
stream.mixer.audioIO.codec.destination = .pcm
stream.mixer.audioIO.codec.settings.format = .pcm
stream.mixer.audioIO.codec.inSourceFormat = config?.audioStreamBasicDescription()
case .raw?:
if stream.mixer.audioIO.codec.inSourceFormat == nil {
stream.mixer.audioIO.codec.destination = .pcm
stream.mixer.audioIO.codec.settings.format = .pcm
stream.mixer.audioIO.codec.inSourceFormat = makeAudioStreamBasicDescription()
}
if let audioBuffer = makeAudioBuffer(stream) {