add AudioEffect filter

This commit is contained in:
shogo4405 2019-07-06 15:44:22 +09:00
parent 97260ca1d2
commit ceced10d3d
10 changed files with 69 additions and 26 deletions

View File

@ -27,7 +27,7 @@ final class LiveViewController: UIViewController {
var rtmpConnection = RTMPConnection()
var rtmpStream: RTMPStream!
var sharedObject: RTMPSharedObject!
var currentEffect: VisualEffect?
var currentEffect: VideoEffect?
@IBOutlet private weak var lfView: GLHKView?
@IBOutlet private weak var currentFPSLabel: UILabel?
@ -175,16 +175,16 @@ final class LiveViewController: UIViewController {
}
@IBAction func onEffectValueChanged(_ segment: UISegmentedControl) {
if let currentEffect: VisualEffect = currentEffect {
_ = rtmpStream.unregisterEffect(video: currentEffect)
if let currentEffect: VideoEffect = currentEffect {
_ = rtmpStream.unregisterVideoEffect(currentEffect)
}
switch segment.selectedSegmentIndex {
case 1:
currentEffect = MonochromeEffect()
_ = rtmpStream.registerEffect(video: currentEffect!)
_ = rtmpStream.registerVideoEffect(currentEffect!)
case 2:
currentEffect = PronamaEffect()
_ = rtmpStream.registerEffect(video: currentEffect!)
_ = rtmpStream.registerVideoEffect(currentEffect!)
default:
break
}

View File

@ -2,7 +2,7 @@ import AVFoundation
import HaishinKit
import UIKit
final class CurrentTimeEffect: VisualEffect {
final class CurrentTimeEffect: VideoEffect {
let filter: CIFilter? = CIFilter(name: "CISourceOverCompositing")
@ -28,7 +28,7 @@ final class CurrentTimeEffect: VisualEffect {
}
}
final class PronamaEffect: VisualEffect {
final class PronamaEffect: VideoEffect {
let filter: CIFilter? = CIFilter(name: "CISourceOverCompositing")
var extent = CGRect.zero {
@ -60,7 +60,7 @@ final class PronamaEffect: VisualEffect {
}
}
final class MonochromeEffect: VisualEffect {
final class MonochromeEffect: VideoEffect {
let filter: CIFilter? = CIFilter(name: "CIColorMonochrome")
override func execute(_ image: CIImage, info: CMSampleBuffer?) -> CIImage {

View File

@ -59,6 +59,9 @@
293875DD1F374D4B009F4B30 /* Logboard.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 293875DC1F374D4B009F4B30 /* Logboard.framework */; };
293875DF1F374D6E009F4B30 /* Logboard.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 293875DE1F374D6E009F4B30 /* Logboard.framework */; };
293875E11F374D80009F4B30 /* Logboard.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 293875E01F374D80009F4B30 /* Logboard.framework */; };
2941746B22D069B300A2944F /* AudioEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2941746A22D069B300A2944F /* AudioEffect.swift */; };
2941746C22D069B300A2944F /* AudioEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2941746A22D069B300A2944F /* AudioEffect.swift */; };
2941746D22D069B300A2944F /* AudioEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2941746A22D069B300A2944F /* AudioEffect.swift */; };
2942424D1CF4C01300D65DCB /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2942424C1CF4C01300D65DCB /* MD5.swift */; };
2942A4F821A9418A004E1BEE /* Running.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2942A4F721A9418A004E1BEE /* Running.swift */; };
2942A4F921A9418A004E1BEE /* Running.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2942A4F721A9418A004E1BEE /* Running.swift */; };
@ -164,7 +167,7 @@
29B876901CD70AFE00FC07DA /* AudioIOComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B876891CD70AFE00FC07DA /* AudioIOComponent.swift */; };
29B876921CD70AFE00FC07DA /* AVMixer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B8768B1CD70AFE00FC07DA /* AVMixer.swift */; };
29B876941CD70AFE00FC07DA /* SoundTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B8768D1CD70AFE00FC07DA /* SoundTransform.swift */; };
29B876961CD70AFE00FC07DA /* VisualEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B8768F1CD70AFE00FC07DA /* VisualEffect.swift */; };
29B876961CD70AFE00FC07DA /* VideoEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B8768F1CD70AFE00FC07DA /* VideoEffect.swift */; };
29B8769B1CD70B1100FC07DA /* MIME.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B876971CD70B1100FC07DA /* MIME.swift */; };
29B8769C1CD70B1100FC07DA /* NetClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B876981CD70B1100FC07DA /* NetClient.swift */; };
29B8769D1CD70B1100FC07DA /* NetService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B876991CD70B1100FC07DA /* NetService.swift */; };
@ -202,7 +205,7 @@
29B877051CD70D5A00FC07DA /* AVMixer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B8768B1CD70AFE00FC07DA /* AVMixer.swift */; };
29B877071CD70D5A00FC07DA /* SoundTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B8768D1CD70AFE00FC07DA /* SoundTransform.swift */; };
29B877081CD70D5A00FC07DA /* VideoIOComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B8768E1CD70AFE00FC07DA /* VideoIOComponent.swift */; };
29B877091CD70D5A00FC07DA /* VisualEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B8768F1CD70AFE00FC07DA /* VisualEffect.swift */; };
29B877091CD70D5A00FC07DA /* VideoEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B8768F1CD70AFE00FC07DA /* VideoEffect.swift */; };
29B8770A1CD70D5A00FC07DA /* MIME.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B876971CD70B1100FC07DA /* MIME.swift */; };
29B8770B1CD70D5A00FC07DA /* NetClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B876981CD70B1100FC07DA /* NetClient.swift */; };
29B8770C1CD70D5A00FC07DA /* NetService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B876991CD70B1100FC07DA /* NetService.swift */; };
@ -298,7 +301,7 @@
29EB3E111ED05881001CAE8B /* IOComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2976A4801D49025B00B53EF2 /* IOComponent.swift */; };
29EB3E131ED05887001CAE8B /* SoundTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B8768D1CD70AFE00FC07DA /* SoundTransform.swift */; };
29EB3E141ED05889001CAE8B /* VideoIOComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B8768E1CD70AFE00FC07DA /* VideoIOComponent.swift */; };
29EB3E151ED0588C001CAE8B /* VisualEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B8768F1CD70AFE00FC07DA /* VisualEffect.swift */; };
29EB3E151ED0588C001CAE8B /* VideoEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B8768F1CD70AFE00FC07DA /* VideoEffect.swift */; };
29EB3E161ED0588F001CAE8B /* MIME.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B876971CD70B1100FC07DA /* MIME.swift */; };
29EB3E171ED05893001CAE8B /* NetClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B876981CD70B1100FC07DA /* NetClient.swift */; };
29EB3E181ED05896001CAE8B /* NetService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B876991CD70B1100FC07DA /* NetService.swift */; };
@ -475,6 +478,7 @@
293875DC1F374D4B009F4B30 /* Logboard.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Logboard.framework; path = Carthage/Build/iOS/Logboard.framework; sourceTree = "<group>"; };
293875DE1F374D6E009F4B30 /* Logboard.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Logboard.framework; path = Carthage/Build/Mac/Logboard.framework; sourceTree = "<group>"; };
293875E01F374D80009F4B30 /* Logboard.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Logboard.framework; path = Carthage/Build/tvOS/Logboard.framework; sourceTree = "<group>"; };
2941746A22D069B300A2944F /* AudioEffect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioEffect.swift; sourceTree = "<group>"; };
2942424C1CF4C01300D65DCB /* MD5.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MD5.swift; sourceTree = "<group>"; };
2942A4F721A9418A004E1BEE /* Running.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Running.swift; sourceTree = "<group>"; };
2945CBBD1B4BE66000104112 /* HaishinKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = HaishinKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@ -556,7 +560,7 @@
29B8768B1CD70AFE00FC07DA /* AVMixer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AVMixer.swift; sourceTree = "<group>"; };
29B8768D1CD70AFE00FC07DA /* SoundTransform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SoundTransform.swift; sourceTree = "<group>"; };
29B8768E1CD70AFE00FC07DA /* VideoIOComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoIOComponent.swift; sourceTree = "<group>"; };
29B8768F1CD70AFE00FC07DA /* VisualEffect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VisualEffect.swift; sourceTree = "<group>"; };
29B8768F1CD70AFE00FC07DA /* VideoEffect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoEffect.swift; sourceTree = "<group>"; };
29B876971CD70B1100FC07DA /* MIME.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MIME.swift; sourceTree = "<group>"; };
29B876981CD70B1100FC07DA /* NetClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetClient.swift; sourceTree = "<group>"; };
29B876991CD70B1100FC07DA /* NetService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetService.swift; sourceTree = "<group>"; };
@ -1016,14 +1020,15 @@
29BDE0BD1C65BC2400D6A768 /* Media */ = {
isa = PBXGroup;
children = (
2941746A22D069B300A2944F /* AudioEffect.swift */,
29B876891CD70AFE00FC07DA /* AudioIOComponent.swift */,
29B8768B1CD70AFE00FC07DA /* AVMixer.swift */,
2976A47D1D48C5C700B53EF2 /* AVRecorder.swift */,
2976A4801D49025B00B53EF2 /* IOComponent.swift */,
295891001EEB7A8B00CE51E1 /* ScalingMode.swift */,
29B8768D1CD70AFE00FC07DA /* SoundTransform.swift */,
29B8768F1CD70AFE00FC07DA /* VideoEffect.swift */,
29B8768E1CD70AFE00FC07DA /* VideoIOComponent.swift */,
29B8768F1CD70AFE00FC07DA /* VisualEffect.swift */,
);
path = Media;
sourceTree = "<group>";
@ -1548,6 +1553,7 @@
files = (
295891161EEB8DFC00CE51E1 /* FLVTagType.swift in Sources */,
29B876B11CD70B2800FC07DA /* RTMPMessage.swift in Sources */,
2941746B22D069B300A2944F /* AudioEffect.swift in Sources */,
295891011EEB7A8B00CE51E1 /* ScalingMode.swift in Sources */,
299B131D1D35272D00A1E8F5 /* ScreenCaptureSession.swift in Sources */,
2915EC4D1D85BB8C00621092 /* RTMPTSocket.swift in Sources */,
@ -1604,7 +1610,7 @@
29B876BC1CD70B3900FC07DA /* ByteArray.swift in Sources */,
29B876831CD70AE800FC07DA /* AudioSpecificConfig.swift in Sources */,
295891121EEB8D7200CE51E1 /* FLVFrameType.swift in Sources */,
29B876961CD70AFE00FC07DA /* VisualEffect.swift in Sources */,
29B876961CD70AFE00FC07DA /* VideoEffect.swift in Sources */,
29EA87F01E79A4120043A5F8 /* CMSampleTimingInfo+Extension.swift in Sources */,
29B876691CD70AB300FC07DA /* Constants.swift in Sources */,
29B8766D1CD70AB300FC07DA /* DataConvertible.swift in Sources */,
@ -1696,6 +1702,7 @@
292D8A341D8B294900DBECE2 /* MP4Sampler.swift in Sources */,
29B876FD1CD70D5A00FC07DA /* AudioSpecificConfig.swift in Sources */,
2958911F1EEB8E9600CE51E1 /* FLVSoundRate.swift in Sources */,
2941746C22D069B300A2944F /* AudioEffect.swift in Sources */,
296242631D8DBA8C00C451A3 /* TSReader.swift in Sources */,
29B876FE1CD70D5A00FC07DA /* H264+AVC.swift in Sources */,
295891171EEB8DFC00CE51E1 /* FLVTagType.swift in Sources */,
@ -1718,7 +1725,7 @@
2976A47F1D48FD6900B53EF2 /* AVRecorder.swift in Sources */,
29B877071CD70D5A00FC07DA /* SoundTransform.swift in Sources */,
29B877081CD70D5A00FC07DA /* VideoIOComponent.swift in Sources */,
29B877091CD70D5A00FC07DA /* VisualEffect.swift in Sources */,
29B877091CD70D5A00FC07DA /* VideoEffect.swift in Sources */,
29B8770A1CD70D5A00FC07DA /* MIME.swift in Sources */,
29B8770B1CD70D5A00FC07DA /* NetClient.swift in Sources */,
29EA87EE1E79A3E30043A5F8 /* CVPixelBuffer+Extension.swift in Sources */,
@ -1824,7 +1831,8 @@
295891101EEB8D3C00CE51E1 /* FLVVideoCodec.swift in Sources */,
295891031EEB7AFC00CE51E1 /* ScalingMode.swift in Sources */,
29EB3DFD1ED05847001CAE8B /* CVPixelBuffer+Extension.swift in Sources */,
29EB3E151ED0588C001CAE8B /* VisualEffect.swift in Sources */,
2941746D22D069B300A2944F /* AudioEffect.swift in Sources */,
29EB3E151ED0588C001CAE8B /* VideoEffect.swift in Sources */,
29EB3E061ED05865001CAE8B /* MP4Sampler.swift in Sources */,
29EB3E041ED05860001CAE8B /* H264+AVC.swift in Sources */,
29EB3DEF1ED05766001CAE8B /* H264Decoder.swift in Sources */,

View File

@ -15,6 +15,8 @@ public class AudioConverter: NSObject {
case setPropertyError(id: AudioConverterPropertyID, status: OSStatus)
}
var effects: Set<AudioEffect> = []
public enum Destination {
case AAC
case PCM
@ -280,6 +282,12 @@ public class AudioConverter: NSObject {
return
}
if !effects.isEmpty {
for effect in effects {
effect.execute(currentBufferList, format: inSourceFormat)
}
}
if muted {
for i in 0..<currentBufferList!.count {
memset(currentBufferList![i].mData, 0, Int(currentBufferList![i].mDataByteSize))

View File

@ -0,0 +1,7 @@
import AVFoundation
import Foundation
open class AudioEffect: NSObject {
open func execute(_ buffer: UnsafeMutableAudioBufferListPointer?, format: AudioStreamBasicDescription?) {
}
}

View File

@ -137,6 +137,14 @@ final class AudioIOComponent: IOComponent {
audioFormat = nil
}
#endif
func registerEffect(_ effect: AudioEffect) -> Bool {
return encoder.effects.insert(effect).inserted
}
func unregisterEffect(_ effect: AudioEffect) -> Bool {
return encoder.effects.remove(effect) != nil
}
}
extension AudioIOComponent: AVCaptureAudioDataOutputSampleBufferDelegate {

View File

@ -2,7 +2,7 @@ import AVFoundation
import CoreImage
import Foundation
open class VisualEffect: NSObject {
open class VideoEffect: NSObject {
open var ciContext: CIContext?
open func execute(_ image: CIImage, info: CMSampleBuffer?) -> CIImage {

View File

@ -48,7 +48,7 @@ final class VideoIOComponent: IOComponent {
return queue
}()
private(set) var effects: Set<VisualEffect> = []
private(set) var effects: Set<VideoEffect> = []
private var extent = CGRect.zero {
didSet {
@ -431,12 +431,12 @@ final class VideoIOComponent: IOComponent {
return image
}
func registerEffect(_ effect: VisualEffect) -> Bool {
func registerEffect(_ effect: VideoEffect) -> Bool {
effect.ciContext = context
return effects.insert(effect).inserted
}
func unregisterEffect(_ effect: VisualEffect) -> Bool {
func unregisterEffect(_ effect: VideoEffect) -> Bool {
effect.ciContext = nil
return effects.remove(effect) != nil
}

View File

@ -175,18 +175,30 @@ open class NetStream: NSObject {
}
}
open func registerEffect(video effect: VisualEffect) -> Bool {
open func registerVideoEffect(_ effect: VideoEffect) -> Bool {
return mixer.videoIO.lockQueue.sync {
self.mixer.videoIO.registerEffect(effect)
}
}
open func unregisterEffect(video effect: VisualEffect) -> Bool {
open func unregisterVideoEffect(_ effect: VideoEffect) -> Bool {
return mixer.videoIO.lockQueue.sync {
self.mixer.videoIO.unregisterEffect(effect)
}
}
open func registerAudioEffect(_ effect: AudioEffect) -> Bool {
return mixer.audioIO.lockQueue.sync {
self.mixer.audioIO.registerEffect(effect)
}
}
open func unregisterAudioEffect(_ effect: AudioEffect) -> Bool {
return mixer.audioIO.lockQueue.sync {
self.mixer.audioIO.unregisterEffect(effect)
}
}
open func dispose() {
lockQueue.async {
self.mixer.dispose()

View File

@ -428,15 +428,15 @@ open class RTMPConnection: EventDispatcher {
stream.on(timer: timer)
}
if measureInterval <= previousQueueBytesOut.count {
var count: Int = 0
var total: Int = 0
for i in 0..<previousQueueBytesOut.count - 1 where previousQueueBytesOut[i] < previousQueueBytesOut[i + 1] {
count += 1
total += 1
}
if count == measureInterval - 1 {
if total == measureInterval - 1 {
for (_, stream) in streams {
stream.delegate?.didPublishInsufficientBW(stream, withConnection: self)
}
} else if count == 0 {
} else if total == 0 {
for (_, stream) in streams {
stream.delegate?.didPublishSufficientBW(stream, withConnection: self)
}