Android: потоковое аудио через TCP-сокеты
Для моего приложения мне нужно записать аудио с MIC на Android-телефоне и отправить его через TCP на другой Android-телефон, где он должен быть воспроизведен.
Я использую класс AudioRecord
и AudioTrack
. Это отлично работает с файлом - записывайте аудио в файл с помощью DataOutputStream
и читайте его с помощью DataInputStream
.
Однако, если я получаю один и тот же поток из сокета вместо файла и пытаюсь записать его, я получаю исключение.
Я затрудняюсь понять, что может произойти неправильно. Любая помощь будет принята с благодарностью.
EDIT: проблема такая же, даже если я пытаюсь с большими размерами буфера (65535 байт, 160000 байт).
Это код:
Recorder:
int bufferSize = AudioRecord.getMinBufferSize(11025, , AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
AudioRecord recordInstance = new AudioRecord(MediaRecorder.AudioSource.MIC, 11025, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
byte[] tempBuffer = new byte[bufferSize];
recordInstance.startRecording();
while (/*isRecording*/) {
bufferRead = recordInstance.read(tempBuffer, 0, bufferSize);
dataOutputStreamInstance.write(tempBuffer);
}
DataOutputStream выше получается как:
BufferedOutputStream buff = new BufferedOutputStream(out1); //out1 is the socket outputStream
DataOutputStream dataOutputStreamInstance = new DataOutputStream (buff);
Не могли бы вы взглянуть, и дайте мне знать, что я могу здесь делать неправильно?
Спасибо,
Ответы
Ответ 1
Я получил эту работу с некоторой помощью и только частично.
Я начал с кода http://emeadev.blogspot.com/2009/09/raw-audio-manipulation-in-android.html, изменил потоки файлов на потоки Socket и изменил isAvailable() на if (inputStream.read(byteArray)!= -1).
Прямая передача аудио через TCP происходит сейчас.
Однако
Все, что я слышу на другом конце, это шум, и теперь я ищу правильный набор параметров для AudioRecorder и AudioTrack - частоту, конфигурацию и кодировку канала, источник звука и т.д.
Если у вас есть представление об этом, сообщите мне.
Спасибо,
EDIT:
Это была глупая ошибка с моей стороны.
В дополнение ко всему, что я сказал выше, используйте inputStream на стороне игрока и outputStream на стороне рекордера, а массивы байтов вместо шорт, и он будет работать.:)
Ответ 2
Не зная конкретного исключения, которое вы получаете, трудно точно знать, что случилось. Это также поможет увидеть код, который вы используете, для создания out1
(т.е. Вашего кода сокета).
Что-то, на что вы можете обратить внимание, это количество данных, считанных с recordInstance.read()
; вы можете не получить из него целый bufferSize
фрагмент данных, поэтому вам нужно позаботиться только о том, чтобы записать байты 0
через bufferRead-1
в выходной разъем.