From 970bea7db2d4b7962681f92f953cf717de8b958c Mon Sep 17 00:00:00 2001 From: Zakk Date: Fri, 15 May 2020 00:11:52 -0400 Subject: [PATCH] Drop frames if the compressor queue gets too deep (hardcoded to 10 frames, may make it dynamic later?) Re-enable proper restoration of audio input source settings (oops) Clear layout source list if a layout recording is stopped and there is no longer a recorder attached to the layout Fix OAuth request percent encoding for auth codes Don't change ffmpeg input source size on input file swap Uninit audio unit with setting input stream format Start of virtual camera plugin (soooooon). Disabled for now Update Youtube output plugin --- .../CSFFMpegCapturePlugin/CSFFMpegCapture.m | 6 +- CocoaSplit.xcodeproj/project.pbxproj | 28 ++ .../xcschemes/CocoaSplit.xcscheme | 95 ++++++ CocoaSplit/CAMultiAudio/CAMultiAudioNode.m | 2 +- CocoaSplit/CSAudioInputSource.m | 2 +- CocoaSplit/CSOauth2Authenticator.m | 2 +- CocoaSplit/CaptureController.m | 4 + CocoaSplit/Compressor/CompressorBase.m | 6 + .../project.pbxproj | 318 ++++++++++++++++++ .../CSVirtualCameraDevice.h | 52 +++ .../CSVirtualCameraDevice.m | 118 +++++++ .../CSVirtualCameraOutput.h | 21 ++ .../CSVirtualCameraOutput.m | 42 +++ .../CSVirtualCameraOutputService.h | 18 + .../CSVirtualCameraOutputService.m | 31 ++ .../CSVirtualCameraOutput/Info.plist | 26 ++ .../CSYoutubeStreamService.m | 1 + .../CSYoutubeStreamServicePlugin/Info.plist | 4 +- 18 files changed, 769 insertions(+), 7 deletions(-) create mode 100644 CocoaSplit.xcodeproj/xcshareddata/xcschemes/CocoaSplit.xcscheme create mode 100644 StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput.xcodeproj/project.pbxproj create mode 100644 StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraDevice.h create mode 100644 StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraDevice.m create mode 100644 StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraOutput.h create mode 100644 StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraOutput.m create mode 100644 StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraOutputService.h create mode 100644 StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraOutputService.m create mode 100644 StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/Info.plist diff --git a/CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/CSFFMpegCapture.m b/CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/CSFFMpegCapture.m index baf0b194..07d34952 100644 --- a/CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/CSFFMpegCapture.m +++ b/CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/CSFFMpegCapture.m @@ -425,8 +425,10 @@ if (use_buf) { - - _lastSize = NSMakeSize(CVPixelBufferGetWidth(use_buf), CVPixelBufferGetHeight(use_buf)); + if (NSEqualSizes(_lastSize, NSZeroSize)) + { + _lastSize = NSMakeSize(CVPixelBufferGetWidth(use_buf), CVPixelBufferGetHeight(use_buf)); + } if ((cTime - _lastTimeUpdate > 0.5) && self.updateMovieTime) { diff --git a/CocoaSplit.xcodeproj/project.pbxproj b/CocoaSplit.xcodeproj/project.pbxproj index 5b58da52..29f0cb97 100644 --- a/CocoaSplit.xcodeproj/project.pbxproj +++ b/CocoaSplit.xcodeproj/project.pbxproj @@ -408,6 +408,13 @@ remoteGlobalIDString = 34799CE2243F0F1300B432BB; remoteInfo = CSLUTFilter; }; + 34A40731246320D200BD32BB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 34A40714246320D100BD32BB /* CSVirtualCameraOutput.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 34A4070B246320D100BD32BB; + remoteInfo = CSVirtualCameraOutput; + }; 34A7C1A019B9A41A00BC6882 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 34A7C19C19B9A41900BC6882 /* CSLayoutSwitcherExtraPlugin.xcodeproj */; @@ -995,6 +1002,7 @@ 34A27229205D99D000135A5D /* CSTransitionCollectionItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSTransitionCollectionItem.h; sourceTree = ""; }; 34A2722A205D99D000135A5D /* CSTransitionCollectionItem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSTransitionCollectionItem.m; sourceTree = ""; }; 34A2722B205D99D000135A5D /* CSTransitionCollectionItem.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CSTransitionCollectionItem.xib; sourceTree = ""; }; + 34A40714246320D100BD32BB /* CSVirtualCameraOutput.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CSVirtualCameraOutput.xcodeproj; path = StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput.xcodeproj; sourceTree = ""; }; 34A629431FBB6DC500B4E16A /* CSJSAnimationDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSJSAnimationDelegate.h; sourceTree = ""; }; 34A629441FBB6DC500B4E16A /* CSJSAnimationDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSJSAnimationDelegate.m; sourceTree = ""; }; 34A6295D1FBB6F0D00B4E16A /* CSJSAnimationDelegateJSExport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSJSAnimationDelegateJSExport.h; sourceTree = ""; }; @@ -2085,6 +2093,14 @@ path = Interface/TransitionSwitcherView; sourceTree = ""; }; + 34A40715246320D100BD32BB /* Products */ = { + isa = PBXGroup; + children = ( + 34A40732246320D200BD32BB /* CSVirtualCameraOutput.bundle */, + ); + name = Products; + sourceTree = ""; + }; 34A7C19D19B9A41900BC6882 /* Products */ = { isa = PBXGroup; children = ( @@ -2248,6 +2264,7 @@ 34AFC2E619B08C1E0007C07B /* StreamServicePlugins */ = { isa = PBXGroup; children = ( + 34A40714246320D100BD32BB /* CSVirtualCameraOutput.xcodeproj */, 344036782080AF71004BC514 /* CSMixerStreamServicePlugin.xcodeproj */, 34BE2B442014F41300E37382 /* CSNewTekNDIStreamServicePlugin.xcodeproj */, 3473D2791D4C349700842EEE /* CSVaughnliveStreamServicePlugin.xcodeproj */, @@ -2652,6 +2669,10 @@ ProductGroup = 3473D27A1D4C349700842EEE /* Products */; ProjectRef = 3473D2791D4C349700842EEE /* CSVaughnliveStreamServicePlugin.xcodeproj */; }, + { + ProductGroup = 34A40715246320D100BD32BB /* Products */; + ProjectRef = 34A40714246320D100BD32BB /* CSVirtualCameraOutput.xcodeproj */; + }, { ProductGroup = 34AFC25519B05B470007C07B /* Products */; ProjectRef = 34576C9819AFE6F7007BAD90 /* CSWindowCapturePlugin.xcodeproj */; @@ -2729,6 +2750,13 @@ remoteRef = 34799CFA243F0F1400B432BB /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 34A40732246320D200BD32BB /* CSVirtualCameraOutput.bundle */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = CSVirtualCameraOutput.bundle; + remoteRef = 34A40731246320D200BD32BB /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 34A7C1A119B9A41A00BC6882 /* CSLayoutSwitcherExtraPlugin.bundle */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; diff --git a/CocoaSplit.xcodeproj/xcshareddata/xcschemes/CocoaSplit.xcscheme b/CocoaSplit.xcodeproj/xcshareddata/xcschemes/CocoaSplit.xcscheme new file mode 100644 index 00000000..848f2a45 --- /dev/null +++ b/CocoaSplit.xcodeproj/xcshareddata/xcschemes/CocoaSplit.xcscheme @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CocoaSplit/CAMultiAudio/CAMultiAudioNode.m b/CocoaSplit/CAMultiAudio/CAMultiAudioNode.m index 5520fda6..89fd563a 100644 --- a/CocoaSplit/CAMultiAudio/CAMultiAudioNode.m +++ b/CocoaSplit/CAMultiAudio/CAMultiAudioNode.m @@ -304,7 +304,7 @@ UInt32 inNumberFrames, -(bool)setInputStreamFormat:(AVAudioFormat *)format bus:(UInt32)bus { - //AudioUnitUninitialize(self.audioUnit); + AudioUnitUninitialize(self.audioUnit); OSStatus err = AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, bus, format.streamDescription, sizeof(AudioStreamBasicDescription)); diff --git a/CocoaSplit/CSAudioInputSource.m b/CocoaSplit/CSAudioInputSource.m index 0ae2b245..51681291 100644 --- a/CocoaSplit/CSAudioInputSource.m +++ b/CocoaSplit/CSAudioInputSource.m @@ -390,7 +390,7 @@ //self.audioVolume = self.audioVolume; if (_savedAudioSettings) { - //[self.audioNode restoreDataFromDict:_savedAudioSettings]; + [self.audioNode restoreDataFromDict:_savedAudioSettings]; } } } diff --git a/CocoaSplit/CSOauth2Authenticator.m b/CocoaSplit/CSOauth2Authenticator.m index fec376de..877bbdc9 100644 --- a/CocoaSplit/CSOauth2Authenticator.m +++ b/CocoaSplit/CSOauth2Authenticator.m @@ -413,7 +413,7 @@ NSString *const kCSOauth2ClientSecret = @"CSOauth2ClientSecret"; request.HTTPMethod = @"POST"; NSDictionary *queryDict = @{@"grant_type": @"authorization_code", - @"code": forCode, + @"code": [forCode stringByRemovingPercentEncoding], @"redirect_uri": redirectURL, @"client_id": self.clientID, @"client_secret": clientSecret }; diff --git a/CocoaSplit/CaptureController.m b/CocoaSplit/CaptureController.m index 1281886a..0e1b78e5 100644 --- a/CocoaSplit/CaptureController.m +++ b/CocoaSplit/CaptureController.m @@ -1376,6 +1376,10 @@ NSString *const CSAppearanceSystem = @"CSAppearanceSystem"; if (useRecorder) { [useRecorder stopRecordingForOutput:output]; + if (!layout.recorder) + { + [layout clearSourceList]; + } //output.active = NO; if (self.mainLayoutRecorder) { diff --git a/CocoaSplit/Compressor/CompressorBase.m b/CocoaSplit/Compressor/CompressorBase.m index 91701bdc..fcbf4a04 100644 --- a/CocoaSplit/Compressor/CompressorBase.m +++ b/CocoaSplit/Compressor/CompressorBase.m @@ -125,7 +125,13 @@ } @synchronized (self) { + //If the queue is too deep, start dropping old frames + if (_compressQueue.count > 10) + { + CapturedFrameData *dontCare = [self consumeframeData]; + } [_compressQueue addObject:frameData]; + dispatch_semaphore_signal(_queueSemaphore); } diff --git a/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput.xcodeproj/project.pbxproj b/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput.xcodeproj/project.pbxproj new file mode 100644 index 00000000..ad206e8e --- /dev/null +++ b/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput.xcodeproj/project.pbxproj @@ -0,0 +1,318 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 34A407382463263F00BD32BB /* CSVirtualCameraDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A407372463263F00BD32BB /* CSVirtualCameraDevice.m */; }; + 34A4073B2463274D00BD32BB /* CSVirtualCameraOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A4073A2463274D00BD32BB /* CSVirtualCameraOutput.m */; }; + 34A4073E246327DF00BD32BB /* CSVirtualCameraOutputService.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A4073D246327DF00BD32BB /* CSVirtualCameraOutputService.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 34A4070B246320D100BD32BB /* CSVirtualCameraOutput.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CSVirtualCameraOutput.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 34A4070E246320D100BD32BB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 34A407362463263F00BD32BB /* CSVirtualCameraDevice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSVirtualCameraDevice.h; sourceTree = ""; }; + 34A407372463263F00BD32BB /* CSVirtualCameraDevice.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSVirtualCameraDevice.m; sourceTree = ""; }; + 34A407392463274D00BD32BB /* CSVirtualCameraOutput.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSVirtualCameraOutput.h; sourceTree = ""; }; + 34A4073A2463274D00BD32BB /* CSVirtualCameraOutput.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSVirtualCameraOutput.m; sourceTree = ""; }; + 34A4073C246327DF00BD32BB /* CSVirtualCameraOutputService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSVirtualCameraOutputService.h; sourceTree = ""; }; + 34A4073D246327DF00BD32BB /* CSVirtualCameraOutputService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSVirtualCameraOutputService.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 34A40708246320D100BD32BB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 34A40702246320D100BD32BB = { + isa = PBXGroup; + children = ( + 34A4070D246320D100BD32BB /* CSVirtualCameraOutput */, + 34A4070C246320D100BD32BB /* Products */, + ); + sourceTree = ""; + }; + 34A4070C246320D100BD32BB /* Products */ = { + isa = PBXGroup; + children = ( + 34A4070B246320D100BD32BB /* CSVirtualCameraOutput.bundle */, + ); + name = Products; + sourceTree = ""; + }; + 34A4070D246320D100BD32BB /* CSVirtualCameraOutput */ = { + isa = PBXGroup; + children = ( + 34A4070E246320D100BD32BB /* Info.plist */, + 34A407362463263F00BD32BB /* CSVirtualCameraDevice.h */, + 34A407372463263F00BD32BB /* CSVirtualCameraDevice.m */, + 34A407392463274D00BD32BB /* CSVirtualCameraOutput.h */, + 34A4073A2463274D00BD32BB /* CSVirtualCameraOutput.m */, + 34A4073C246327DF00BD32BB /* CSVirtualCameraOutputService.h */, + 34A4073D246327DF00BD32BB /* CSVirtualCameraOutputService.m */, + ); + path = CSVirtualCameraOutput; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 34A4070A246320D100BD32BB /* CSVirtualCameraOutput */ = { + isa = PBXNativeTarget; + buildConfigurationList = 34A40711246320D100BD32BB /* Build configuration list for PBXNativeTarget "CSVirtualCameraOutput" */; + buildPhases = ( + 34A40707246320D100BD32BB /* Sources */, + 34A40708246320D100BD32BB /* Frameworks */, + 34A40709246320D100BD32BB /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CSVirtualCameraOutput; + productName = CSVirtualCameraOutput; + productReference = 34A4070B246320D100BD32BB /* CSVirtualCameraOutput.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 34A40703246320D100BD32BB /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1120; + ORGANIZATIONNAME = Zakk; + TargetAttributes = { + 34A4070A246320D100BD32BB = { + CreatedOnToolsVersion = 11.2.1; + }; + }; + }; + buildConfigurationList = 34A40706246320D100BD32BB /* Build configuration list for PBXProject "CSVirtualCameraOutput" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 34A40702246320D100BD32BB; + productRefGroup = 34A4070C246320D100BD32BB /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 34A4070A246320D100BD32BB /* CSVirtualCameraOutput */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 34A40709246320D100BD32BB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 34A40707246320D100BD32BB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 34A4073E246327DF00BD32BB /* CSVirtualCameraOutputService.m in Sources */, + 34A407382463263F00BD32BB /* CSVirtualCameraDevice.m in Sources */, + 34A4073B2463274D00BD32BB /* CSVirtualCameraOutput.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 34A4070F246320D100BD32BB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 34A40710246320D100BD32BB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + }; + name = Release; + }; + 34A40712246320D100BD32BB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = L3JLUY4S5E; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../CocoaSplit/PluginHeaders"; + INFOPLIST_FILE = CSVirtualCameraOutput/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; + OTHER_LDFLAGS = ( + "-undefined", + suppress, + "-flat_namespace", + ); + PRODUCT_BUNDLE_IDENTIFIER = zakk.lol.CSVirtualCameraOutput; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 34A40713246320D100BD32BB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = L3JLUY4S5E; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../CocoaSplit/PluginHeaders"; + INFOPLIST_FILE = CSVirtualCameraOutput/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; + OTHER_LDFLAGS = ( + "-undefined", + suppress, + "-flat_namespace", + ); + PRODUCT_BUNDLE_IDENTIFIER = zakk.lol.CSVirtualCameraOutput; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 34A40706246320D100BD32BB /* Build configuration list for PBXProject "CSVirtualCameraOutput" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 34A4070F246320D100BD32BB /* Debug */, + 34A40710246320D100BD32BB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 34A40711246320D100BD32BB /* Build configuration list for PBXNativeTarget "CSVirtualCameraOutput" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 34A40712246320D100BD32BB /* Debug */, + 34A40713246320D100BD32BB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 34A40703246320D100BD32BB /* Project object */; +} diff --git a/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraDevice.h b/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraDevice.h new file mode 100644 index 00000000..2a00ee22 --- /dev/null +++ b/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraDevice.h @@ -0,0 +1,52 @@ +// +// CSVirtualCameraDevice.h +// CSVirtualCamera +// +// Created by Zakk on 5/6/20. +// Copyright © 2020 Zakk. All rights reserved. +// + +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + + +@protocol CSVirtualCameraProtocol +-(void)publishNewFrame:(NSString *)deviceUUID withIOSurface:(IOSurface *)ioSurface; +-(void)createDevice:(NSString *)name withUID:(NSString *)uid withModel:(NSString *)modelName withManufacturer:(NSString *)manufacturer width:(NSUInteger)width height:(NSUInteger)height pixelFormat:(OSType)pixelFormat frameRate:(float) frameRate withReply:(void (^)(NSString *))reply; +-(void)destroyDevice:(NSString *)uuid; +-(void)setInternalClock:(bool)useClock forDevice:(NSString *)deviceUUID; +-(void)setPersistOnDisconnect:(bool)persist forDevice:(NSString *)deviceUUID; + +@end + + +@interface CSVirtualCameraDevice : NSObject +{ + NSXPCConnection *_XPCconnection; + id _assistant; +} + + +@property (strong) NSString *name; +@property (strong) NSString *deviceUID; +@property (strong) NSString *modelName; +@property (strong) NSString *manufacturer; +@property (assign) float frameRate; +@property (assign) UInt32 width; +@property (assign) UInt32 height; +@property (assign) OSType pixelFormat; +@property (assign) bool isReady; +@property (assign) bool useInternalClock; +@property (assign) bool persistOnDisconnect; + +-(void)createDeviceWithCompletionBlock:(void (^)(void))completionBlock; +-(void)destroyDevice; +-(void)publishCVPixelBufferFrame:(CVPixelBufferRef)videoFrame; +-(void)publishIOSurfaceFrame:(IOSurface *)videoFrame; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraDevice.m b/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraDevice.m new file mode 100644 index 00000000..b8c79907 --- /dev/null +++ b/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraDevice.m @@ -0,0 +1,118 @@ +// +// CSVirtualCameraDevice.m +// CSVirtualCamera +// +// Created by Zakk on 5/6/20. +// Copyright © 2020 Zakk. All rights reserved. +// + +#import "CSVirtualCameraDevice.h" + +@implementation CSVirtualCameraDevice + +@synthesize useInternalClock = _useInternalClock; +@synthesize persistOnDisconnect = _persistOnDisconnect; + + +-(void)connectToAssistant +{ + NSXPCInterface *assistantInterface = [NSXPCInterface interfaceWithProtocol:@protocol(CSVirtualCameraProtocol)]; + NSXPCConnection *connection = [[NSXPCConnection alloc] initWithMachServiceName:@"com.cocoasplit.vcam.assistant" options:0]; + [connection setRemoteObjectInterface:assistantInterface]; + [connection resume]; + _assistant = [connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + NSLog(@"Could not connect to remote Assistant"); + }]; + _XPCconnection = connection; +} + + +-(void)setPersistOnDisconnect:(bool)persist +{ + _persistOnDisconnect = persist; + if (_assistant) + { + [_assistant setPersistOnDisconnect:persist forDevice:self.deviceUID]; + } +} + +-(bool)persistOnDisconnect +{ + return _persistOnDisconnect; +} + + + +-(void)setUseInternalClock:(bool)useClock +{ + _useInternalClock = useClock; + if (_assistant) + { + [_assistant setInternalClock:useClock forDevice:self.deviceUID]; + } +} + +-(bool)useInternalClock +{ + return _useInternalClock; +} + +-(void)createDeviceWithCompletionBlock:(void (^)(void))completionBlock +{ + if (!_assistant) + { + [self connectToAssistant]; + } + + + [_assistant createDevice:self.name withUID:self.deviceUID withModel:self.modelName withManufacturer:self.manufacturer width:self.width height:self.height pixelFormat:self.pixelFormat frameRate:self.frameRate withReply:^(NSString * _Nonnull uid) { + self.isReady = YES; + if (completionBlock) + { + completionBlock(); + } + }]; +} + + +-(void)destroyDevice +{ + [_assistant destroyDevice:self.deviceUID]; +} + + +-(void)publishCVPixelBufferFrame:(CVPixelBufferRef)videoFrame +{ + if (!_assistant) + { + return; + } + + IOSurface *bufferSurface = (__bridge IOSurface *)(CVPixelBufferGetIOSurface(videoFrame)); + + if (bufferSurface) + { + [self publishIOSurfaceFrame:bufferSurface]; + } else { + //Supported later + } +} + + +-(void)publishIOSurfaceFrame:(IOSurface *)videoFrame +{ + if (!_assistant) + { + return; + } + [_assistant publishNewFrame:self.deviceUID withIOSurface:videoFrame]; +} + +-(void)dealloc +{ + +} +@end + + + diff --git a/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraOutput.h b/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraOutput.h new file mode 100644 index 00000000..3a6b46c6 --- /dev/null +++ b/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraOutput.h @@ -0,0 +1,21 @@ +// +// CSVirtualCameraOutput.h +// CSVirtualCameraOutput +// +// Created by Zakk on 5/6/20. +// Copyright © 2020 Zakk. All rights reserved. +// + +#import +#import "CSOutputBase.h" +#import "CSVirtualCameraDevice.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface CSVirtualCameraOutput : CSOutputBase +{ + CSVirtualCameraDevice *_cameraDevice; +} +@end + +NS_ASSUME_NONNULL_END diff --git a/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraOutput.m b/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraOutput.m new file mode 100644 index 00000000..a64ffc2f --- /dev/null +++ b/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraOutput.m @@ -0,0 +1,42 @@ +// +// CSVirtualCameraOutput.m +// CSVirtualCameraOutput +// +// Created by Zakk on 5/6/20. +// Copyright © 2020 Zakk. All rights reserved. +// + +#import "CSVirtualCameraOutput.h" + +@implementation CSVirtualCameraOutput + + +-(bool)queueFramedata:(CapturedFrameData *)frameData +{ + + CVPixelBufferRef useImage = CMSampleBufferGetImageBuffer(frameData.encodedSampleBuffer); + if (!useImage) + { + return NO; + } + if (!_cameraDevice) + { + _cameraDevice = [[CSVirtualCameraDevice alloc] init]; + _cameraDevice.deviceUID = @"CocoaSplit Test Output"; + _cameraDevice.frameRate = 60.0f; + _cameraDevice.width = CVPixelBufferGetWidth(useImage); + _cameraDevice.height = CVPixelBufferGetHeight(useImage); + _cameraDevice.name = @"CocoaSplit Test Output"; + _cameraDevice.pixelFormat = CVPixelBufferGetPixelFormatType(useImage); + [_cameraDevice createDeviceWithCompletionBlock:^{ + _cameraDevice.persistOnDisconnect = NO; + }]; + return NO; //We'll start next frame or so + } else if (_cameraDevice.isReady) { + [_cameraDevice publishCVPixelBufferFrame:useImage]; + return YES; + } + + return NO; +} +@end diff --git a/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraOutputService.h b/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraOutputService.h new file mode 100644 index 00000000..c1160249 --- /dev/null +++ b/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraOutputService.h @@ -0,0 +1,18 @@ +// +// CSVirtualCameraOutputService.h +// CSVirtualCameraOutput +// +// Created by Zakk on 5/6/20. +// Copyright © 2020 Zakk. All rights reserved. +// + +#import +#import "CSStreamServiceBase.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface CSVirtualCameraOutputService : CSStreamServiceBase + +@end + +NS_ASSUME_NONNULL_END diff --git a/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraOutputService.m b/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraOutputService.m new file mode 100644 index 00000000..5a2a2f37 --- /dev/null +++ b/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/CSVirtualCameraOutputService.m @@ -0,0 +1,31 @@ +// +// CSVirtualCameraOutputService.m +// CSVirtualCameraOutput +// +// Created by Zakk on 5/6/20. +// Copyright © 2020 Zakk. All rights reserved. +// + +#import "CSVirtualCameraOutputService.h" +#import "CSVirtualCameraOutput.h" + +@implementation CSVirtualCameraOutputService + ++(NSString *)label +{ + return @"Virtual Camera"; +} + +-(NSObject *)createOutput +{ + return [[CSVirtualCameraOutput alloc] init]; +} + + +-(NSString *)getServiceDestination +{ + return @"COCOASPLIT"; +} + + +@end diff --git a/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/Info.plist b/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/Info.plist new file mode 100644 index 00000000..6a9bbcdb --- /dev/null +++ b/StreamServicePlugins/CSVirtualCameraOutput/CSVirtualCameraOutput/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + NSHumanReadableCopyright + Copyright © 2020 Zakk. All rights reserved. + NSPrincipalClass + CSVirtualCameraOutputService + + diff --git a/StreamServicePlugins/CSYoutubeStreamServicePlugin/CSYoutubeStreamServicePlugin/CSYoutubeStreamService.m b/StreamServicePlugins/CSYoutubeStreamServicePlugin/CSYoutubeStreamServicePlugin/CSYoutubeStreamService.m index 6e7d5830..b6e08d83 100644 --- a/StreamServicePlugins/CSYoutubeStreamServicePlugin/CSYoutubeStreamServicePlugin/CSYoutubeStreamService.m +++ b/StreamServicePlugins/CSYoutubeStreamServicePlugin/CSYoutubeStreamServicePlugin/CSYoutubeStreamService.m @@ -272,6 +272,7 @@ [self.oauthObject jsonRequest:apiRequest completionHandler:^(id decodedData) { NSDictionary *user_response = (NSDictionary *)decodedData; + NSString *account_name = [user_response objectForKey:@"email"]; [authenticator saveToKeychain:account_name]; diff --git a/StreamServicePlugins/CSYoutubeStreamServicePlugin/CSYoutubeStreamServicePlugin/Info.plist b/StreamServicePlugins/CSYoutubeStreamServicePlugin/CSYoutubeStreamServicePlugin/Info.plist index 615726dc..50903325 100644 --- a/StreamServicePlugins/CSYoutubeStreamServicePlugin/CSYoutubeStreamServicePlugin/Info.plist +++ b/StreamServicePlugins/CSYoutubeStreamServicePlugin/CSYoutubeStreamServicePlugin/Info.plist @@ -25,8 +25,8 @@ NSPrincipalClass CSYoutubeStreamService YoutubeClientID - 997237227687-ubgm910gsivg6g0v00qgm0sgngq1o0oe.apps.googleusercontent.com + 963493379025-dhonfmg481m0quul8dbdepfc4954h3lj.apps.googleusercontent.com YoutubeClientSecret - xvgH6PQpQkVDCfxNGHvkJiim + EUj7vTJl3c7HqWzplbiq9ItB