流式传输实时音频

Posted

技术标签:

【中文标题】流式传输实时音频【英文标题】:Streaming Real time Audio 【发布时间】:2012-04-03 23:04:49 【问题描述】:

我希望在 android 设备上具有实时音频流功能,该功能通过设备的 MIC 捕获音频并将其发送到服务器。我知道在录制后发送音频文件,但在实时情况下我需要帮助。可能可以通过不断地向服务器发送字节数组来完成。如果是这样,如何或如果有任何其他方式,请分享您的想法。谢谢。

编辑-

Android 客户端代码:-

public class Main extends Activity 
    private MediaRecorder recorder;

    private final String TAG = "AudioTest";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        String hostname = "192.168.50.25";
        int port = 2004;

        Socket socket = null;
        try 
            socket = new Socket(InetAddress.getByName(hostname), port);

         catch (UnknownHostException e) 

            Log.d(TAG, "Inside  UnknownHostException@@@@@@@@@@@@@@@@@@@@@@");

            e.printStackTrace();
         catch (IOException e) 
            Log.d(TAG, "Inside  IOException%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");

            e.printStackTrace();
        

        ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);

        recorder = new MediaRecorder();
        recorder.setAudiosource(MediaRecorder.AudioSource.MIC);
        recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

        recorder.setOutputFile(pfd.getFileDescriptor());


        try 
            Log.i(TAG, pfd.getFileDescriptor().toString());
         catch (Exception e) 
            Log.d(TAG, "Inside  MyException################################");
        

        try 
            recorder.prepare();
         catch (IllegalStateException e) 

            e.printStackTrace();
         catch (IOException e) 

            e.printStackTrace();
        

        recorder.start();

    

JAVA服务器代码-

public class Provider 
    ServerSocket providerSocket;
    Socket connection = null;
    ObjectOutputStream out;
    ObjectInputStream in;
    String message;

    Provider() 
    

    void run() 
        try 
            // 1. creating a server socket
            providerSocket = new ServerSocket(2004, 10);
            // 2. Wait for connection
            System.out.println("Waiting for connection");

            connection = providerSocket.accept();
            System.out.println("Connection received from "
                    + connection.getInetAddress().getHostName());
            // 3. get Input and Output streams
            out = new ObjectOutputStream(connection.getOutputStream());
            out.flush();
            in = new ObjectInputStream(connection.getInputStream());
            sendMessage("Connection successful");
            // 4. The two parts communicate via the input and output streams
            do 
                try 
                    message = (String) in.readObject();
                    System.out.println("client>" + message);
                    if (message.equals("bye"))
                        sendMessage("bye");
                 catch (ClassNotFoundException classnot) 
                    System.err.println("Data received in unknown format");
                
             while (!message.equals("bye"));
         catch (IOException ioException) 
            ioException.printStackTrace();
         finally 
            // 4: Closing connection
            try 
                in.close();
                out.close();
                providerSocket.close();
             catch (IOException ioException) 
                ioException.printStackTrace();
            
        
    

    void sendMessage(String msg) 
        try 
            out.writeObject(msg);
            out.flush();
            System.out.println("server>" + msg);
         catch (IOException ioException) 
            ioException.printStackTrace();
        
    

    public static void main(String args[]) 
        Provider server = new Provider();
        while (true) 
            server.run();
        
    

【问题讨论】:

【参考方案1】:

你可以这样使用套接字:

String hostname = "1.2.3.4";
int port = 865;

Socket socket = null;

try 
    socket = new Socket(InetAddress.getByName(hostname), port);
 catch (Exception e) 

    e.printStackTrace();


ParcelFileDescriptor socketedFile = ParcelFileDescriptor.fromSocket(socket);

然后将socketedFile设置为录音机的输出文件(socketedFile.getFileDescriptor())。这会将其作为字节发送。

或者,为了使其更稳定,将数据从 MediaRecorder 写入本地缓冲区,然后让单独的线程检查该缓冲区并将其写入套接字,以允许套接字连接中的小断开连接。

有关更多信息,请参阅此问题:android stream audio to server

显然,您需要在服务器上运行一个应用程序来接收您的字节并将其转换为音频数据。

【讨论】:

嗨米奇...非常感谢您的关注。但是我遇到了另一个异常(java.io.StreamCorruptedException:无效的流标头:00000018)。如果可以,请在这方面提供帮助。请参阅已编辑的问题。

以上是关于流式传输实时音频的主要内容,如果未能解决你的问题,请参考以下文章

通过 socket.io 流式传输实时音频

具有不同长度的音频文件的 HTTP 实时流式传输

将实时 Android 音频流式传输到服务器

使用 Flash 流式传输实时音频

Qt 通过 TCP 套接字实时流式传输音频

ExoPlayer 无法播放 Adob​​e 实时流编码器流式传输的音频/视频 (RTMP)