Skip to content

Commit de3c48c

Browse files
committed
添加双声道aac
Change-Id: Iffafcbab42a88e6819788b874ab90809d828d682
1 parent f846c54 commit de3c48c

13 files changed

+166
-113
lines changed

Source/LinkSDKDemo/Video/P2P/Controller/TIoTDemoPreviewDeviceVC.m

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,17 @@ - (void)getDeviceStatusWithType:(NSString *)singleType qualityType:(NSString *)q
257257
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
258258
[[AVAudioSession sharedInstance] setActive:YES error:nil];
259259

260-
[[TIoTCoreXP2PBridge sharedInstance] sendVoiceToServer:weakSelf.deviceName?:@"" channel:channel];
260+
// [[TIoTCoreXP2PBridge sharedInstance] sendVoiceToServer:weakSelf.deviceName?:@"" channel:channel];
261+
TIoTCoreAudioConfig *audio_config = [TIoTCoreAudioConfig new];
262+
audio_config.sampleRate = TIoTAVCaptionFLVAudio_8;
263+
audio_config.channels = 1;
264+
audio_config.isEchoCancel = NO;
265+
266+
TIoTCoreVideoConfig *video_config = [TIoTCoreVideoConfig new];
267+
video_config.localView = nil;
268+
video_config.videoPosition = AVCaptureDevicePositionFront;
269+
270+
[[TIoTCoreXP2PBridge sharedInstance] sendVoiceToServer:weakSelf.deviceName?:@"" channel:channel audioConfig:audio_config videoConfig:video_config];
261271
}
262272

263273
}else {

Source/SDK/LinkVideo/FLV/TIoTAACEncoder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#import <Foundation/Foundation.h>
33
#import <AVFoundation/AVFoundation.h>
44
#import <AudioToolbox/AudioToolbox.h>
5-
#import "TIoTAVCaptionFLV.h"
5+
#import "TIoTCoreAudioConfig.h"
66

77
@protocol TIoTAACEncoderDelegate <NSObject>
88
- (void)getEncoderAACData:(NSData *)data;

Source/SDK/LinkVideo/FLV/TIoTAACEncoder.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ - (void)setUpConverter {
5858
outAudioStreamBasicDescription.mBytesPerFrame = 0;
5959
outAudioStreamBasicDescription.mFramesPerPacket = 1024;
6060
//设定声道数为1
61-
outAudioStreamBasicDescription.mChannelsPerFrame = 1;
61+
outAudioStreamBasicDescription.mChannelsPerFrame = inAudioStreamBasicDescription.mChannelsPerFrame;
6262
//设定采样率为16000
6363
// outAudioStreamBasicDescription.mSampleRate = inAudioStreamBasicDescription.mSampleRate;
6464
if (self.audioType == TIoTAVCaptionFLVAudio_8) {
@@ -145,14 +145,14 @@ -(void)encodePCMData:(NSData *)pcmdata {
145145
FillComplexInputParm userParam;
146146
userParam.source = pcmData;
147147
userParam.sourceSize = (UInt32)pcmLength;
148-
userParam.channelCount = 1;
148+
userParam.channelCount = self->inAudioStreamBasicDescription.mChannelsPerFrame;
149149
userParam.packetDescription = NULL;
150150
//在堆区创建audiobufferlist
151151
AudioBufferList outputBufferList;
152152
outputBufferList.mNumberBuffers = 1;
153153
outputBufferList.mBuffers[0].mData = outputBuffer;
154154
outputBufferList.mBuffers[0].mDataByteSize = (UInt32)pcmLength;
155-
outputBufferList.mBuffers[0].mNumberChannels = 1;
155+
outputBufferList.mBuffers[0].mNumberChannels = self->inAudioStreamBasicDescription.mChannelsPerFrame;
156156
//编码
157157
OSStatus status = AudioConverterFillComplexBuffer(self->convertContext->converter, audioConverterComplexInputDataProc, &userParam, &packetSize, &outputBufferList, outputPacketDes);
158158
free(outputPacketDes);
@@ -257,7 +257,7 @@ - (NSData*) adtsDataForPacketLength:(NSUInteger)packetLength {
257257
// else if (self.audioType == TIoTAVCaptionFLVAudio_441) {
258258
// freqIdx = 4;
259259
// }
260-
int chanCfg = 1; //MPEG-4 Audio Channel Configuration. 1 Channel front-center
260+
int chanCfg = inAudioStreamBasicDescription.mChannelsPerFrame; //MPEG-4 Audio Channel Configuration. 1 Channel front-center
261261
NSUInteger fullLength = adtsLength + packetLength;
262262
// fill in ADTS data
263263
packet[0] = (char)0xFF; // 11111111 = syncword

Source/SDK/LinkVideo/FLV/TIoTAVCaptionFLV.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11

22
#import <UIKit/UIKit.h>
3-
#import <AVFoundation/AVFoundation.h>
4-
5-
typedef NS_ENUM(NSInteger, TIoTAVCaptionFLVAudioType) {
6-
TIoTAVCaptionFLVAudio_8,
7-
TIoTAVCaptionFLVAudio_16
8-
};
3+
#import "TIoTCoreAudioConfig.h"
4+
#import "TIoTCoreVideoConfig.h"
95

106
@protocol TIoTAVCaptionFLVDelegate <NSObject>
117
-(void) capture:(uint8_t *)data len:(size_t) size;
@@ -17,7 +13,7 @@ typedef NS_ENUM(NSInteger, TIoTAVCaptionFLVAudioType) {
1713
@property (nonatomic, assign)UIView *videoLocalView;
1814
@property (nonatomic, assign)BOOL isEchoCancel;
1915
@property (nonatomic, assign)AVCaptureDevicePosition devicePosition;
20-
-(instancetype) initWithAudioConfig:(TIoTAVCaptionFLVAudioType)audioSampleRate;
16+
-(instancetype) initWithAudioConfig:(TIoTAVCaptionFLVAudioType)audioSampleRate channel:(int)channel;
2117

2218
- (void)preStart;
2319
- (BOOL)startCapture;

Source/SDK/LinkVideo/FLV/TIoTAVCaptionFLV.mm

Lines changed: 19 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -23,33 +23,30 @@ @interface TIoTAVCaptionFLV ()<AVCaptureVideoDataOutputSampleBufferDelegate,AVCa
2323
@property (nonatomic, strong) AVCaptureSession *session;
2424
// 队列
2525
@property (nonatomic, strong) dispatch_queue_t videoQueue;
26-
@property (nonatomic, strong) dispatch_queue_t AudioQueue;
2726

2827
// 负责从 AVCaptureDevice 获得输入数据
2928
@property (nonatomic, strong) AVCaptureDeviceInput *deviceInput;
3029
@property (nonatomic, strong) AVCaptureVideoDataOutput *videoOutput;
3130
@property (nonatomic, strong) AVCaptureConnection *videoConnection;
32-
@property (nonatomic, strong) AVCaptureConnection *audioConnection;
3331
// 拍摄预览图层
3432
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;
3533
@property (nonatomic, strong) TIoTH264Encoder *h264Encoder;
3634
@property (nonatomic, strong) TIoTAACEncoder *aacEncoder;
37-
//@property (nonatomic, strong) NSMutableData *data;
38-
//@property (nonatomic, copy ) NSString *h264File;
39-
//@property (nonatomic, strong) NSFileHandle *fileHandle;
4035
@property (nonatomic, assign) TIoTAVCaptionFLVAudioType audioRate;
36+
@property (nonatomic, assign) int channel;
4137
@property (nonatomic, assign) int captureVideoFPS;
4238
@property (nonatomic, strong) AVCaptureSessionPreset resolutionRatioValue;
4339
@property (nonatomic, strong) TIoTPCMXEchoRecord *pcmRecord;
4440
@end
4541

4642
@implementation TIoTAVCaptionFLV
4743

48-
-(instancetype) initWithAudioConfig:(TIoTAVCaptionFLVAudioType)audioSampleRate {
44+
-(instancetype) initWithAudioConfig:(TIoTAVCaptionFLVAudioType)audioSampleRate channel:(int)channel {
4945
self = [super init];
5046
if (self) {
5147
tAVCaptionFLV = self;
5248
_audioRate = audioSampleRate;
49+
_channel = channel;
5350
_isEchoCancel = NO;
5451
_devicePosition = AVCaptureDevicePositionBack;
5552
[self onInit];
@@ -68,7 +65,6 @@ -(void) onInit{
6865

6966
muxerQueue = dispatch_queue_create("FLV_Muxer_Queue", DISPATCH_QUEUE_SERIAL);
7067

71-
// _data = [NSMutableData new];
7268
_session = [AVCaptureSession new];
7369

7470
self.resolutionRatioValue = AVCaptureSessionPreset352x288;
@@ -82,52 +78,17 @@ - (void)setupAudioCapture {
8278
return;
8379
}
8480
AudioStreamBasicDescription inAudioStreamBasicDescription;
85-
if (_isEchoCancel) {
8681

87-
self.pcmRecord = [[TIoTPCMXEchoRecord alloc] init];
88-
[self.pcmRecord set_record_callback:record_callback user:(__bridge void * _Nonnull)(self)];
89-
// [self.record start_record];
90-
91-
inAudioStreamBasicDescription = self.pcmRecord.pcmStreamDescription;
92-
self.aacEncoder = [[TIoTAACEncoder alloc] initWithAudioDescription:inAudioStreamBasicDescription];
93-
self.aacEncoder.delegate = self;
94-
self.aacEncoder.audioType = _audioRate;
95-
return;
96-
}
82+
self.pcmRecord = [[TIoTPCMXEchoRecord alloc] initWithChannel:_channel isEcho:_isEchoCancel];
83+
[self.pcmRecord set_record_callback:record_callback user:(__bridge void * _Nonnull)(self)];
84+
// [self.record start_record];
85+
86+
inAudioStreamBasicDescription = self.pcmRecord.pcmStreamDescription;
9787
self.aacEncoder = [[TIoTAACEncoder alloc] initWithAudioDescription:inAudioStreamBasicDescription];
9888
self.aacEncoder.delegate = self;
9989
self.aacEncoder.audioType = _audioRate;
100-
101-
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
102-
103-
NSError *error = nil;
104-
105-
AVCaptureDeviceInput *audioInput = [[AVCaptureDeviceInput alloc]initWithDevice:audioDevice error:&error];
106-
107-
if (error) {
108-
109-
NSLog(@"Error getting audio input device:%@",error.description);
110-
}
111-
112-
if ([self.session canAddInput:audioInput]) {
113-
114-
[self.session addInput:audioInput];
115-
}
116-
117-
self.AudioQueue = dispatch_queue_create("Audio Capture Queue", DISPATCH_QUEUE_SERIAL);
118-
119-
AVCaptureAudioDataOutput *audioOutput = [AVCaptureAudioDataOutput new];
120-
[audioOutput setSampleBufferDelegate:self queue:self.AudioQueue];
121-
122-
if ([self.session canAddOutput:audioOutput]) {
123-
124-
[self.session addOutput:audioOutput];
125-
}
126-
127-
self.audioConnection = [audioOutput connectionWithMediaType:AVMediaTypeAudio];
128-
129-
13090
}
91+
13192
- (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition)position
13293
{
13394
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
@@ -349,17 +310,10 @@ - (void)calculatorCaptureFPS {
349310

350311
#pragma mark - 实现 AVCaptureOutputDelegate:
351312
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
352-
if (connection == _videoConnection) { // Video
353-
354-
if (self.videoLocalView) { //开关打开,才推送视频
355-
[self.h264Encoder encode:sampleBuffer];
356-
357-
[self calculatorCaptureFPS];
358-
}
359-
360-
} else if (connection == _audioConnection) { // Audio
313+
if (self.videoLocalView) { //开关打开,才推送视频
314+
[self.h264Encoder encode:sampleBuffer];
361315

362-
[self.aacEncoder encodeSampleBuffer:sampleBuffer];
316+
[self calculatorCaptureFPS];
363317
}
364318
}
365319

@@ -415,6 +369,7 @@ - (void)gotEncodedData:(NSData*)data isKeyFrame:(BOOL)isKeyFrame {
415369

416370
#pragma mark - TIoTAACEncoderDelegate
417371
- (void)getEncoderAACData:(NSData *)data {
372+
// [_fileHandle writeData:data];
418373
encodeFlvData(0, data);
419374
}
420375

@@ -500,26 +455,22 @@ -(BOOL) startCapture {
500455
// NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
501456
// NSString *documentsDirectory = [paths firstObject];
502457

503-
// self.h264File = [documentsDirectory stringByAppendingPathComponent:@"lyh.h264"];
504-
// [fileManager removeItemAtPath:self.h264File error:nil];
505-
// [fileManager createFileAtPath:self.h264File contents:nil attributes:nil];
506-
// _fileHandle = [NSFileHandle fileHandleForWritingAtPath:self.h264File];
458+
// NSString *h264File = [documentsDirectory stringByAppendingPathComponent:@"lyh.aac"];
459+
// [fileManager removeItemAtPath:h264File error:nil];
460+
// [fileManager createFileAtPath:h264File contents:nil attributes:nil];
461+
// _fileHandle = [NSFileHandle fileHandleForWritingAtPath:h264File];
507462

508463
flv_init_load();
509464

510465
[self startCamera];
511466

512-
if (_isEchoCancel) {
513-
[self.pcmRecord start_record];
514-
}
467+
[self.pcmRecord start_record];
515468
return YES;
516469
}
517470

518471
-(void) stopCapture{
519472
[self stopCarmera];
520-
if (_isEchoCancel) {
521-
[self.pcmRecord stop_record];
522-
}
473+
[self.pcmRecord stop_record];
523474
}
524475

525476
- (void) startCamera
@@ -551,15 +502,6 @@ - (void) stopCarmera
551502
// [_fileHandle closeFile];
552503
// _fileHandle = NULL;
553504
//
554-
// 获取程序Documents目录路径
555-
/*NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
556-
NSString *documentsDirectory = [paths objectAtIndex:0];
557-
558-
NSMutableString * path = [[NSMutableString alloc]initWithString:documentsDirectory];
559-
[path appendString:@"/AACFile.aac"];
560-
561-
[_data writeToFile:path atomically:YES];
562-
*/
563505
}
564506

565507
- (void)setCameraFPS:(int)fps {

Source/SDK/LinkVideo/FLV/TIoTPCMXEchoRecord.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ NS_ASSUME_NONNULL_BEGIN
99
@interface TIoTPCMXEchoRecord : NSObject
1010
@property (nonatomic, assign, readonly)AudioStreamBasicDescription pcmStreamDescription;
1111

12+
- (instancetype)initWithChannel:(int)channel isEcho:(BOOL)isEcho;
1213
- (void)set_record_callback:(RecordCallback)c user:(void *)u;
1314
- (void)start_record;
1415
- (void)stop_record;

Source/SDK/LinkVideo/FLV/TIoTPCMXEchoRecord.mm

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,14 @@
1010
@interface TIoTPCMXEchoRecord()
1111
{
1212
AudioUnit audioUnit;
13-
std::queue<std::pair<std::shared_ptr<char>, int>> queue;
14-
std::mutex mutex;
1513
RecordCallback callback;
1614
void *user;
1715
}
1816

1917
@end
18+
2019
@implementation TIoTPCMXEchoRecord
21-
- (instancetype)init
20+
- (instancetype)initWithChannel:(int)channel isEcho:(BOOL)isEcho
2221
{
2322
self = [super init];
2423
if (!self) return nil;
@@ -28,7 +27,11 @@ - (instancetype)init
2827
des.componentFlagsMask = 0;
2928
des.componentManufacturer = kAudioUnitManufacturer_Apple;
3029
des.componentType = kAudioUnitType_Output;
31-
des.componentSubType = kAudioUnitSubType_VoiceProcessingIO; //kAudioUnitSubType_RemoteIO;
30+
if (isEcho) {
31+
des.componentSubType = kAudioUnitSubType_VoiceProcessingIO; //kAudioUnitSubType_RemoteIO;
32+
}else {
33+
des.componentSubType = kAudioUnitSubType_RemoteIO;
34+
}
3235

3336
AudioComponent audioComponent;
3437
audioComponent = AudioComponentFindNext(NULL, &des);
@@ -41,10 +44,10 @@ - (instancetype)init
4144
outStreamDes.mFormatID = kAudioFormatLinearPCM;
4245
outStreamDes.mFormatFlags = kAudioFormatFlagIsSignedInteger;
4346
outStreamDes.mFramesPerPacket = 1;
44-
outStreamDes.mChannelsPerFrame = 1;
47+
outStreamDes.mChannelsPerFrame = channel;
4548
outStreamDes.mBitsPerChannel = 16;
46-
outStreamDes.mBytesPerFrame = 2;
47-
outStreamDes.mBytesPerPacket = 2;
49+
outStreamDes.mBytesPerFrame = 2 * channel;
50+
outStreamDes.mBytesPerPacket = 2 * channel;
4851
outStreamDes.mReserved = 0;
4952
_pcmStreamDescription = outStreamDes;
5053

@@ -76,11 +79,12 @@ - (instancetype)init
7679

7780
#define kTVURecoderPCMMaxBuffSize 2048
7881
static int pcm_buffer_size = 0;
79-
static uint8_t pcm_buffer[kTVURecoderPCMMaxBuffSize*2];
82+
static uint8_t pcm_buffer[kTVURecoderPCMMaxBuffSize*4];
8083

8184
static OSStatus record_callback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrame, AudioBufferList *__nullable ioData)
8285
{
8386
TIoTPCMXEchoRecord *r = (__bridge TIoTPCMXEchoRecord *)(inRefCon);
87+
int channel = r->_pcmStreamDescription.mChannelsPerFrame;
8488

8589
AudioBufferList list;
8690
list.mNumberBuffers = 1;
@@ -107,13 +111,13 @@ static OSStatus record_callback(void *inRefCon, AudioUnitRenderActionFlags *ioAc
107111
memcpy(pcm_buffer+pcm_buffer_size, bufferData, bufferSize);
108112
pcm_buffer_size = pcm_buffer_size + bufferSize;
109113

110-
if(pcm_buffer_size >= kTVURecoderPCMMaxBuffSize) {
114+
if(pcm_buffer_size >= (kTVURecoderPCMMaxBuffSize*channel)) {
111115
if (r->callback)
112116
r->callback(pcm_buffer, pcm_buffer_size, r->user);
113117

114118
// 因为采样不可能每次都精准的采集到1024个样点,所以如果大于2048大小就先填满2048,剩下的跟着下一次采集一起送给转换器
115-
memcpy(pcm_buffer, pcm_buffer + kTVURecoderPCMMaxBuffSize, pcm_buffer_size - kTVURecoderPCMMaxBuffSize);
116-
pcm_buffer_size = pcm_buffer_size - kTVURecoderPCMMaxBuffSize;
119+
memcpy(pcm_buffer, pcm_buffer + (kTVURecoderPCMMaxBuffSize*channel), pcm_buffer_size - (kTVURecoderPCMMaxBuffSize*channel));
120+
pcm_buffer_size = pcm_buffer_size - (kTVURecoderPCMMaxBuffSize*channel);
117121
}
118122

119123
return error;
@@ -125,15 +129,14 @@ OSStatus outputRender_cb(void *inRefCon, AudioUnitRenderActionFlags *ioActionFla
125129

126130
- (void)start_record
127131
{
132+
pcm_buffer_size = 0;
128133
AudioOutputUnitStart(audioUnit);
129134
}
130135

131136
- (void)stop_record
132137
{
133138
AudioOutputUnitStop(audioUnit);
134-
std::unique_lock<std::mutex> lock(mutex);
135-
decltype(queue) empty;
136-
std::swap(empty, queue);
139+
pcm_buffer_size = 0;
137140
}
138141

139142
- (void)set_record_callback:(RecordCallback)c user:(nonnull void *)u
@@ -146,5 +149,7 @@ - (void)dealloc
146149
{
147150
callback = NULL;
148151
user = NULL;
152+
[self stop_record];
153+
AudioComponentInstanceDispose(audioUnit);
149154
}
150155
@end

0 commit comments

Comments
 (0)