Я хотел передать аудио с iPhone на IP-камеру, это было сделано в android logi c для android ниже:
import java.nio.ByteBuffer;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.media.MediaRecorder;
import android.os.Build;
class AudioEncoder
{
private static final String TAG = "AudioEncoder";
private static final String MIME = "audio/mp4a-latm";
public static final boolean IS_DOUBLE_AUDIO_CHANNEL = false;
private static final int DEFAULT_AUDIO_RATE = 128000;
public static final int DEFAULT_AUDIO_SAMPLE_RATE = 48000;
private int DEFAULT_AUDIO_CHANEL_COUNT = 1;
private int DEFAULT_AUDIO_CHANEL_CONFIG = AudioFormat.CHANNEL_IN_STEREO;
private int DEFAULT_AUDIO_FORMART = AudioFormat.ENCODING_PCM_16BIT;
private MediaCodec mAudioCodec;
private int mAudioBufferSize;
private AudioRecord mAudioRecord;
private AudioEncodeRunnable mAudioEncodeRunnable;
private int mAudioTrack = -1;
private MediaMuxer mMuxer;
private EncodeCallback mEncodeCallback;
private Thread mAudioThread;
public interface EncodeCallback {
public void onAudioFormartChanged(int track);
public void onAudioDataChanged(int track, ByteBuffer buffer, MediaCodec.BufferInfo info);
}
private class AudioEncodeRunnable implements Runnable{
private boolean mCanRun;
public AudioEncodeRunnable(){
mCanRun = true;
}
public void stop(){
mCanRun = false;
mEncodeCallback = null;
}
@Override
public void run() {
// TODO Auto-generated method stub
mAudioBufferSize = AudioRecord.getMinBufferSize(DEFAULT_AUDIO_SAMPLE_RATE,
DEFAULT_AUDIO_CHANEL_CONFIG, DEFAULT_AUDIO_FORMART) * DEFAULT_AUDIO_CHANEL_COUNT;
mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, DEFAULT_AUDIO_SAMPLE_RATE,
DEFAULT_AUDIO_CHANEL_CONFIG, DEFAULT_AUDIO_FORMART, mAudioBufferSize);
MediaFormat format = MediaFormat.createAudioFormat(MIME, DEFAULT_AUDIO_SAMPLE_RATE, DEFAULT_AUDIO_CHANEL_COUNT);
format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
format.setInteger(MediaFormat.KEY_BIT_RATE, DEFAULT_AUDIO_RATE);
try {
mAudioCodec = MediaCodec.createEncoderByType(MIME);
mAudioCodec.configure(format,null,null,MediaCodec.CONFIGURE_FLAG_ENCODE);
} catch (Exception e) {
// TODO: handle exception
}
mAudioCodec.start();
mAudioRecord.startRecording();
while(mCanRun && !Thread.interrupted()){
if(null != mAudioRecord && null != mAudioCodec){
try {
readOutputData();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
if(null != mAudioCodec){
mAudioCodec.stop();
mAudioCodec.release();
}
}
}
private boolean readOutputData() throws Exception{
int index = mAudioCodec.dequeueInputBuffer(-1);
if(index >= 0){
final ByteBuffer buffer = getInputBuffer(index);
buffer.clear();
int length = mAudioRecord.read(buffer, IS_DOUBLE_AUDIO_CHANNEL ? 4096 : 2048 );
//Log.d(TAG, "readOutputData LENGTH="+length);
if(length > 0){
mAudioCodec.queueInputBuffer(index, 0, length, System.nanoTime() / 1000, 0);
}
}
MediaCodec.BufferInfo mInfo = new MediaCodec.BufferInfo();
int outIndex;
do{
outIndex = mAudioCodec.dequeueOutputBuffer(mInfo,0);
if(outIndex >= 0){
ByteBuffer buffer = getOutputBuffer(outIndex);
buffer.position(mInfo.offset);
if(mInfo.size > 0){
if(null != mEncodeCallback){
mEncodeCallback.onAudioDataChanged(mAudioTrack, buffer, mInfo);
}
}
mAudioCodec.releaseOutputBuffer(outIndex,false);
if((mInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0){
return true;
}
}else if(outIndex == MediaCodec.INFO_TRY_AGAIN_LATER){
}else if(outIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED){
if(null != mMuxer){
mAudioTrack = mMuxer.addTrack(mAudioCodec.getOutputFormat());
if(null != mEncodeCallback){
mEncodeCallback.onAudioFormartChanged(mAudioTrack);
}
}
}
}while (outIndex >= 0);
return false;
}
private ByteBuffer getInputBuffer(int index){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return mAudioCodec.getInputBuffer(index);
}else{
return mAudioCodec.getInputBuffers()[index];
}
}
private ByteBuffer getOutputBuffer(int index){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return mAudioCodec.getOutputBuffer(index);
}else{
return mAudioCodec.getOutputBuffers()[index];
}
}
synchronized public void start(){
/*if(null != mAudioEncodeRunnable){
mAudioEncodeRunnable.stop();
mAudioEncodeRunnable = null;
}*/
if(null == mAudioThread){
mAudioEncodeRunnable = new AudioEncodeRunnable();
mAudioThread = new Thread(mAudioEncodeRunnable);
mAudioThread.start();
}
}
synchronized public void stop(){
if(null != mAudioEncodeRunnable){
mAudioEncodeRunnable.stop();
if(null != mAudioThread){
mAudioThread.interrupt();
try {
mAudioThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mAudioThread = null;
}
}
if(mAudioRecord != null){
mAudioRecord.stop();
mAudioRecord.release();
}
}
public AudioEncoder(MediaMuxer muxer, EncodeCallback callback){
mMuxer = muxer;
mEncodeCallback = callback;
if(IS_DOUBLE_AUDIO_CHANNEL){
DEFAULT_AUDIO_CHANEL_COUNT = 2;
DEFAULT_AUDIO_CHANEL_CONFIG = AudioFormat.CHANNEL_IN_STEREO;
}else{
DEFAULT_AUDIO_CHANEL_COUNT = 1;
DEFAULT_AUDIO_CHANEL_CONFIG = AudioFormat.CHANNEL_IN_MONO;
}
}
}
Выше я вставил android код для справки.
Требуется аналогичный код для iOS. Если требуется дополнительная информация, дайте мне знать.
Необходимый аудио кодер для приложения ios.
Заранее спасибо