// // SampleHandler.m // ScreenRecorder // // Created by Drew on 2019/5/9. // Copyright © 2019 The Chromium Authors. All rights reserved. // #import "SampleHandler.h" #import #import static TXLivePush *s_txLivePublisher; static CMSampleBufferRef s_lastSampleBuffer; static int lastOrientation; static int count; //static void onDarwinPushStart(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { // [[NSNotificationCenter defaultCenter] postNotificationName:@"Cocoa_Push_Start" object:nil]; //} static void onDarwinPushStop(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { [[NSNotificationCenter defaultCenter] postNotificationName:@"Cocoa_Push_Stop" object:nil]; } @implementation SampleHandler - (void)broadcastStartedWithSetupInfo:(NSDictionary *)setupInfo { NSString * const licenceURL = @"http://license.vod2.myqcloud.com/license/v1/43ecf97f9d9c3b2ba5e7cd516e2d399e/TXLiveSDK.licence"; NSString * const licenceKey = @"01adf33ae4a8d91a2c6dee88677b6ac8"; [TXLiveBase setLicenceURL:licenceURL key:licenceKey]; // CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), // (__bridge const void *)(self), // onDarwinPushStart, // CFSTR("PUSH_START"), // NULL, // CFNotificationSuspensionBehaviorDeliverImmediately); CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), (__bridge const void *)(self), onDarwinPushStop, CFSTR("PUSH_STOP"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately); // [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePushStartNotification:) name:@"Cocoa_Push_Start" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePushStopNotification:) name:@"Cocoa_Push_Stop" object:nil]; if (s_txLivePublisher) { [s_txLivePublisher stopPush]; } TXLivePushConfig* config = [[TXLivePushConfig alloc] init]; config.audioChannels = 0; config.customModeType |= CUSTOM_MODE_VIDEO_CAPTURE; //自定义视频模式 config.enableAutoBitrate = YES; config.enableHWAcceleration = YES; config.customModeType |= CUSTOM_MODE_AUDIO_CAPTURE; //自定义音频模式 config.audioSampleRate = AUDIO_SAMPLE_RATE_44100; //系统录屏的音频采样率为44100 config.audioChannels = 1; //config.autoSampleBufferSize = YES; config.autoSampleBufferSize = NO; config.sampleBufferSize = CGSizeMake(1280, 720); config.homeOrientation = HOME_ORIENTATION_RIGHT; s_txLivePublisher = [[TXLivePush alloc] initWithConfig:config]; NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.long.dianjing"]; NSString *rtmpUrl = [userDefaults objectForKey:@"rtmpUrl"]; // rtmpUrl = @"rtmp://202.79.174.56:1935/test/test"; if (rtmpUrl == nil) { [self sendLocalNotificationToHostAppWithTitle:@"比赛未开始" msg:@"开始比赛后才能录屏" userInfo:@{@"id":@"LOCAL_NOTIFY_SCHEDULE_ID"}]; NSString *domain = @"com.long.dianjing.ScreenRecorder"; NSDictionary *userInfo = @{ NSLocalizedFailureReasonErrorKey : @"比赛未开始" }; NSError *error = [NSError errorWithDomain:domain code:-101 userInfo:userInfo]; [self finishBroadcastWithError:error]; return; } [self sendLocalNotificationToHostAppWithTitle:@"录屏已开始" msg:@"请开始游戏" userInfo:@{@"id":@"LOCAL_NOTIFY_SCHEDULE_ID"}]; [s_txLivePublisher startPush:rtmpUrl]; } //- (void)handlePushStartNotification:(NSNotification*)noti { // NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.long.dianjing"]; // NSString *rtmpUrl = [userDefaults objectForKey:@"rtmpUrl"]; // if (rtmpUrl == nil) { // [self sendLocalNotificationToHostAppWithTitle:@"比赛未开始" msg:@"开始比赛后才能录屏" userInfo:@{@"id":@"LOCAL_NOTIFY_SCHEDULE_ID"}]; // return; // } // [s_txLivePublisher startPush:rtmpUrl]; // // [self sendLocalNotificationToHostAppWithTitle:@"录屏已开始" msg:@"请开始游戏" userInfo:@{@"id":@"LOCAL_NOTIFY_SCHEDULE_ID"}]; //} // - (void)handlePushStopNotification:(NSNotification*)noti { NSString *domain = @"com.long.dianjing.ScreenRecorder"; NSDictionary *userInfo = @{ NSLocalizedFailureReasonErrorKey : @"比赛完成" }; NSError *error = [NSError errorWithDomain:domain code:-101 userInfo:userInfo]; if (s_txLivePublisher) { [s_txLivePublisher stopPush]; s_txLivePublisher = nil; [self sendLocalNotificationToHostAppWithTitle:@"录屏已结束" msg:@"请等待结算" userInfo:@{@"id":@"LOCAL_NOTIFY_SCHEDULE_ID"}]; } [self finishBroadcastWithError:error]; } - (void)broadcastPaused { [s_txLivePublisher setSendAudioSampleBufferMuted:YES]; } - (void)broadcastResumed { [s_txLivePublisher setSendAudioSampleBufferMuted:NO]; } - (void)broadcastFinished { if (s_txLivePublisher) { [s_txLivePublisher stopPush]; s_txLivePublisher = nil; [self sendLocalNotificationToHostAppWithTitle:@"录屏已结束" msg:@"请等待结算" userInfo:@{@"id":@"LOCAL_NOTIFY_SCHEDULE_ID"}]; } } - (void)processSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType { count++; count = count % 3; switch (sampleBufferType) { case RPSampleBufferTypeVideo: { if (!CMSampleBufferIsValid(sampleBuffer)) return; //保存一帧在startPush时发送,防止推流启动后或切换横竖屏因无画面数据而推流不成功 if (s_lastSampleBuffer) { CFRelease(s_lastSampleBuffer); s_lastSampleBuffer = NULL; } s_lastSampleBuffer = sampleBuffer; CFRetain(s_lastSampleBuffer); if (count == 2) { int orientation = [(__bridge NSString *)CMGetAttachment(sampleBuffer, (CFStringRef)RPVideoSampleOrientationKey, nil) intValue]; if (lastOrientation == 0) { lastOrientation = orientation; } else if (orientation != lastOrientation) { if(8 == orientation){ TXLivePushConfig* config = [s_txLivePublisher config]; config.homeOrientation = HOME_ORIENTATION_LEFT; [s_txLivePublisher setConfig:config]; } else if(6 == orientation){ TXLivePushConfig* config = [s_txLivePublisher config]; config.homeOrientation = HOME_ORIENTATION_RIGHT; [s_txLivePublisher setConfig:config]; } NSLog(@"orientation change to %d", orientation); lastOrientation = orientation; } } [s_txLivePublisher sendVideoSampleBuffer:sampleBuffer]; } break; case RPSampleBufferTypeAudioApp: // Handle audio sample buffer for app audio break; case RPSampleBufferTypeAudioMic: // Handle audio sample buffer for mic audio break; default: break; } } - (void)sendLocalNotificationToHostAppWithTitle:(NSString*)title msg:(NSString*)msg userInfo:(NSDictionary*)userInfo { UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter]; UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init]; content.title = [NSString localizedUserNotificationStringForKey:title arguments:nil]; content.body = [NSString localizedUserNotificationStringForKey:msg arguments:nil]; content.sound = [UNNotificationSound defaultSound]; content.userInfo = userInfo; // 在设定时间后推送本地推送 UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:0.1f repeats:NO]; UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"ReplayKit2Demo" content:content trigger:trigger]; //添加推送成功后的处理! [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { }]; } @end