iOS ijkplayer Audio Unit 播放音频
2017-05-31 15:38
2496 查看
设置AudioUnit的播放的方法参考上一篇文章 此处不再多说
这里给出AudioUnit的代码请查阅
/*
* IJKSDLAudioUnitController.h
*
* Copyright (c) 2013 Bilibili
* Copyright (c) 2013 Zhang Rui <bbcallen@gmail.com>
*
* based on https://github.com/kolyvan/kxmovie *
* This file is part of ijkPlayer.
*
* ijkPlayer is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* ijkPlayer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with ijkPlayer; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import <Foundation/Foundation.h>
#include "ijksdl/ijksdl_aout.h"
@interface IJKSDLAudioUnitController : NSObject
- (id)initWithAudioSpec:(const SDL_AudioSpec *)aSpec;
- (void)play;
- (void)pause;
- (void)flush;
- (void)stop;
- (void)close;
- (void)setPlaybackRate:(float)playbackRate;
- (void)setPlaybackVolume:(float)playbackVolume;
- (double)get_latency_seconds;
@property (nonatomic, readonly) SDL_AudioSpec spec;
@end
这里给出AudioUnit的代码请查阅
/*
* IJKSDLAudioUnitController.h
*
* Copyright (c) 2013 Bilibili
* Copyright (c) 2013 Zhang Rui <bbcallen@gmail.com>
*
* based on https://github.com/kolyvan/kxmovie *
* This file is part of ijkPlayer.
*
* ijkPlayer is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* ijkPlayer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with ijkPlayer; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import <Foundation/Foundation.h>
#include "ijksdl/ijksdl_aout.h"
@interface IJKSDLAudioUnitController : NSObject
- (id)initWithAudioSpec:(const SDL_AudioSpec *)aSpec;
- (void)play;
- (void)pause;
- (void)flush;
- (void)stop;
- (void)close;
- (void)setPlaybackRate:(float)playbackRate;
- (void)setPlaybackVolume:(float)playbackVolume;
- (double)get_latency_seconds;
@property (nonatomic, readonly) SDL_AudioSpec spec;
@end
/* * IJKSDLAudioUnitController.m * * Copyright (c) 2013 Bilibili * Copyright (c) 2013 Zhang Rui <bbcallen@gmail.com> * * based on https://github.com/kolyvan/kxmovie * * This file is part of ijkPlayer. * * ijkPlayer is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * ijkPlayer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with ijkPlayer; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #import "IJKSDLAudioUnitController.h" #import "IJKSDLAudioKit.h" #include "ijksdl/ijksdl_log.h" #import <AVFoundation/AVFoundation.h> @implementation IJKSDLAudioUnitController { AudioUnit _auUnit; BOOL _isPaused; } - (id)initWithAudioSpec:(const SDL_AudioSpec *)aSpec { self = [super init]; if (self) { if (aSpec == NULL) { self = nil; return nil; } _spec = *aSpec; if (aSpec->format != AUDIO_S16SYS) { NSLog(@"aout_open_audio: unsupported format %d\n", (int)aSpec->format); return nil; } if (aSpec->channels > 6) { NSLog(@"aout_open_audio: unsupported channels %d\n", (int)aSpec->channels); return nil; } AudioComponentDescription desc; IJKSDLGetAudioComponentDescriptionFromSpec(&_spec, &desc); AudioComponent auComponent = AudioComponentFindNext(NULL, &desc); if (auComponent == NULL) { ALOGE("AudioUnit: AudioComponentFindNext failed"); self = nil; return nil; } AudioUnit auUnit; OSStatus status = AudioComponentInstanceNew(auComponent, &auUnit); if (status != noErr) { ALOGE("AudioUnit: AudioComponentInstanceNew failed"); self = nil; return nil; } UInt32 flag = 1; status = AudioUnitSetProperty(auUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &flag, sizeof(flag)); if (status != noErr) { ALOGE("AudioUnit: failed to set IO mode (%d)", (int)status); } /* Get the current format */ _spec.format = AUDIO_S16SYS; _spec.channels = 2; AudioStreamBasicDescription streamDescription; IJKSDLGetAudioStreamBasicDescriptionFromSpec(&_spec, &streamDescription); /* Set the desired format */ UInt32 i_param_size = sizeof(streamDescription); status = AudioUnitSetProperty(auUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &streamDescription, i_param_size); if (status != noErr) { ALOGE("AudioUnit: failed to set stream format (%d)", (int)status); self = nil; return nil; } /* Retrieve actual format */ status = AudioUnitGetProperty(auUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &streamDescription, &i_param_size); if (status != noErr) { ALOGE("AudioUnit: failed to verify stream format (%d)\n", (int)status); } AURenderCallbackStruct callback; callback.inputProc = (AURenderCallback) RenderCallback; callback.inputProcRefCon = (__bridge void*) self; status = AudioUnitSetProperty(auUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &callback, sizeof(callback)); if (status != noErr) { ALOGE("AudioUnit: render callback setup failed (%d)\n", (int)status); self = nil; return nil; } SDL_CalculateAudioSpec(&_spec); /* AU initiliaze */ status = AudioUnitInitialize(auUnit); if (status != noErr) { ALOGE("AudioUnit: AudioUnitInitialize failed (%d)\n", (int)status); self = nil; return nil; } _auUnit = auUnit; } return self; } - (void)dealloc { [self close]; } - (void)play { if (!_auUnit) return; _isPaused = NO; NSError *error = nil; if (NO == [[AVAudioSession sharedInstance] setActive:YES error:&error]) { NSLog(@"AudioUnit: AVAudioSession.setActive(YES) failed: %@\n", error ? [error localizedDescription] : @"nil"); } OSStatus status = AudioOutputUnitStart(_auUnit); if (status != noErr) NSLog(@"AudioUnit: AudioOutputUnitStart failed (%d)\n", (int)status); } - (void)pause { if (!_auUnit) return; _isPaused = YES; OSStatus status = AudioOutputUnitStop(_auUnit); if (status != noErr) ALOGE("AudioUnit: failed to stop AudioUnit (%d)\n", (int)status); } - (void)flush { if (!_auUnit) return; AudioUnitReset(_auUnit, kAudioUnitScope_Global, 0); } - (void)stop { if (!_auUnit) return; OSStatus status = AudioOutputUnitStop(_auUnit); if (status != noErr) ALOGE("AudioUnit: failed to stop AudioUnit (%d)", (int)status); } - (void)close { [self stop]; if (!_auUnit) return; AURenderCallbackStruct callback; memset(&callback, 0, sizeof(AURenderCallbackStruct)); AudioUnitSetProperty(_auUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &callback, sizeof(callback)); AudioComponentInstanceDispose(_auUnit); _auUnit = NULL; } - (void)setPlaybackRate:(float)playbackRate { // if (fabsf(playbackRate - 1.0f) <= 0.000001) { // UInt32 propValue = 1; // AudioQueueSetProperty(_audioQueueRef, kAudioQueueProperty_TimePitchBypass, &propValue, sizeof(propValue)); // AudioQueueSetParameter(_audioQueueRef, kAudioQueueParam_PlayRate, 1.0f); // } else { // UInt32 propValue = 0; // AudioQueueSetProperty(_audioQueueRef, kAudioQueueProperty_TimePitchBypass, &propValue, sizeof(propValue)); // AudioQueueSetParameter(_audioQueueRef, kAudioQueueParam_PlayRate, playbackRate); // } } - (void)setPlaybackVolume:(float)playbackVolume { // float aq_volume = playbackVolume; // if (fabsf(aq_volume - 1.0f) <= 0.000001) { // AudioQueueSetParameter(_audioQueueRef, kAudioQueueParam_Volume, 1.f); // } else { // AudioQueueSetParameter(_audioQueueRef, kAudioQueueParam_Volume, aq_volume); // } } //- (double)get_latency_seconds //{ // return ((double)(kIJKAudioQueueNumberBuffers)) * _spec.samples / _spec.freq; //} - (double)get_latency_seconds { return (double) _spec.samples / _spec.freq; } static OSStatus RenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) { @autoreleasepool { IJKSDLAudioUnitController* auController = (__bridge IJKSDLAudioUnitController *) inRefCon; if (!auController || auController->_isPaused) { for (UInt32 i = 0; i < ioData->mNumberBuffers; i++) { AudioBuffer *ioBuffer = &ioData->mBuffers[i]; memset(ioBuffer->mData, auController.spec.silence, ioBuffer->mDataByteSize); } return noErr; } for (int i = 0; i < (int)ioData->mNumberBuffers; i++) { AudioBuffer *ioBuffer = &ioData->mBuffers[i]; (*auController.spec.callback)(auController.spec.userdata, ioBuffer->mData, ioBuffer->mDataByteSize); } return noErr; } } @end
相关文章推荐
- iOS学习——AVAudioPlayer播放本地音频
- iOS ijkplayer 音频数据的播放
- iOS 音视频开发:Audio Unit播放FFmpeg解码的音频
- IOS第三方类 播放音频 STKAudioPlayer
- iOS 音视频高级编程:Audio Unit播放FFmpeg解码的音频
- iOS开发音频播放基础——AVAudioPlayer的应用
- iOS 音视频高级编程:Audio Unit播放FFmpeg解码的音频
- iOS AvPlayer AvAudioPlayer音频的后台播放问题
- ios audioplayer播放声音失败是由于最简单的错误
- iOS AvPlayer AvAudioPlayer音频的后台播放
- [iOS]使用Audio Queue Services 播放和录制音频
- [iOS]使用Audio Queue Services 播放和录制音频
- iOS AvPlayer AvAudioPlayer音频的后台播放问题
- IOS中有三种播放音频的方式:AVAudioPlayer、音频服务、音频队列。
- iOS开发之AVAudioPlayer 音频播放
- iOS开发之AVAudioPlayer 音频播放
- ios 使用Audio Queue Services 播放和录制音频
- iOS开发之AVAudioPlayer 音频播放
- iOS AvPlayer AvAudioPlayer音频的后台播放问题
- iOS使用Audio Queue Services 播放和录制音频