Java通过UDP向Android广播音频

时间:2016-01-26 22:14:57

标签: java android audio broadcast multicastsocket

我正在做一个应用程序,用于接收运行我编写的Java服务器的Raspberry播放的实时音频,并且必须将其广播到多个客户端。现在我正在使用MulticastSocket来实现它。

到目前为止,问题是收到的音频坏了,我不知道为什么。另一个问题是使用Marshmallow Android,它无法加入一组MulticastSocket,当其他设备加入服务器时,音频会自动从Android切断。

Android方面:

import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.util.Log;

import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

public class Receiver implements Runnable {

    private final String SERVER_ADDRESS     = "224.0.0.3";
    private final int    SERVER_PORT        = 48824;

    private final int    SAMPLE_RATE        = 32000;
    private final int    PACKET_SIZE        = 1200;
    private final int    CHANNEL_OUT_MONO   = 4;
    private final int    CHANNEL_OUT_STEREO = 12;

    private static boolean stopTrack = false;

    public static AudioTrack track;
    private static AudioManager am;

    private static InetAddress inetAddress;
    private static MulticastSocket multicastSocket;

    private final int CHANNELS = CHANNEL_OUT_MONO;

    @Override
    public void run() {

        //ESTABLISH CONNECTION
        try{
            inetAddress = InetAddress.getByName(SERVER_ADDRESS);

        }catch(Exception ex){
            Log.e("TCP","Error: server probably closed");
            ex.printStackTrace();
        }

        //am = (AudioManager)Context.getSystemService(Context.AUDIO_SERVICE);
        //int currentVolume = am.getStreamVolume(AudioManager.STREAM_MUSIC);

        stopTrack = false;

        int minSize = AudioTrack.getMinBufferSize(SAMPLE_RATE, CHANNELS, AudioFormat.ENCODING_PCM_16BIT);
        Log.e("AUDIO","minSize = " + minSize);

        track = new AudioTrack( AudioManager.STREAM_MUSIC, SAMPLE_RATE,
                CHANNELS, AudioFormat.ENCODING_PCM_16BIT,
                minSize, AudioTrack.MODE_STREAM);
        track.play();

        try{

            multicastSocket = new MulticastSocket(SERVER_PORT);
            multicastSocket.joinGroup(inetAddress);
            //multicastSocket.setReuseAddress(true);
            //multicastSocket.setBroadcast(true);

            byte[] buffer = new byte[PACKET_SIZE];

            while(!stopTrack){

                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                multicastSocket.receive(packet);
                track.write(packet.getData(), 0, buffer.length);
                //Log.e("ERRO","SOCKET");
            }
            //multicastSocket.close();
        } catch (Exception e) {
            Log.e("UDP", "Receiver error", e);
        }
    }

    public static void stopLiveAudioStream(){
        track.stop();
        multicastSocket.close();
        stopTrack = true;
    }
}

和UDP服务器:

import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.Port;

import java.util.*;
import java.net.*;
import java.io.*;

public class MulticastUDPServer {

    private static final String INET_ADDR   = "224.0.0.3";
    private static final int    SERVER_PORT = 48824;
    private static final int    BUFFER_SIZE = 4096;
    private static final int    PACKET_SIZE = 1200;

    private static DatagramSocket socket;
    private static InetAddress addr;

    public static void main(String[] args){

        Mixer.Info minfo[] = AudioSystem.getMixerInfo();
        System.out.println("STARTING SERVER!");

        try{
            addr = InetAddress.getByName(INET_ADDR);
        }catch(Exception ex){
            System.out.println("ADDRESS ERROR: " + INET_ADDR);
        }

        try(DatagramSocket serverSocket = new DatagramSocket()){

            AudioFormat         format = getAudioFormat();
            DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, format);
            DataLine.Info   sourceInfo = new DataLine.Info(SourceDataLine.class, format);

            SourceDataLine sourceDataLine;

            TargetDataLine targetDataLine = (TargetDataLine)AudioSystem.getLine(dataLineInfo);
            targetDataLine.open(format, BUFFER_SIZE);
            targetDataLine.start();
            sourceDataLine = (SourceDataLine) AudioSystem.getLine(sourceInfo);
            sourceDataLine.open(format, BUFFER_SIZE);
            sourceDataLine.start();

            byte[] targetData = new byte[PACKET_SIZE];

            System.out.println("\n\nBROADCASTING!");

            while(true){

                targetDataLine.read(targetData,0,targetData.length);
                serverSocket.send(new DatagramPacket(targetData, targetData.length, addr, SERVER_PORT));
            }

        }catch(Exception ex){
            ex.printStackTrace();
        }
    }



    private static AudioFormat getAudioFormat() {

        float sampleRate = 32000.0F;
        int sampleSizeBits = 16;
        int channels = 1;
        boolean signed = true;
        boolean bigEndian = false;

        return new AudioFormat(sampleRate, sampleSizeBits, channels, signed, bigEndian);
    }
}

提前致谢。

0 个答案:

没有答案