[Android] Empfangen von RTP-Stream - AudioStream, AudioGroup


Answers

Entschuldigung, wenn das Folgende dumm ist:

Die ffmpeg-Befehlszeile scheint einen Testsound zu erzeugen und sendet ihn als PCM-Datenstrom über RTP.

RTP selbst garantiert keine zuverlässige Zustellung von gestreamten Daten, es liefert nur genügend Informationen, um dem Empfänger mitzuteilen, wenn er alle Daten erhalten hat und genau, welche Daten fehlen, wenn einige während des Transports verloren gegangen sind. Außerdem wird es normalerweise über UDP verwendet.

Daher liegt bei RTP die Betonung auf dem Benutzer von RTP, Daten zu senden, die auf solche Weise codiert sind (dh mit Fehlerkorrekturcodierung, Redundanz in den Daten usw.), so dass der Empfänger genügend der ursprünglichen Daten rekonstruieren kann, um die Anwendungen zu erfüllen braucht. Bei einem Audiostream benötigen Sie also ein Codierungsformat, das Ihren Anforderungen entspricht.

Ich habe keinen Hinweis gefunden, was pcm_u8 bedeutet, aber es ist sehr suggestiv, dass es ein einfacher Pulscode-modulierter Datenstrom mit 8-Bit-Daten ist. Das klingt nicht so, als hätte es eine Fehlerkorrektur-Kodierung oder Datenredundanz eingebaut. Verliert man ein Byte, bedeutet das, dass man ein Sample verliert, und am Empfangsende kann nichts getan werden, um es auszufüllen.

Also denke ich, dass etwas in deinem Netzwerk UDP-Pakete fallen lässt, dass RTP dem AudioStream sagt, welche Daten fehlen und das Ergebnis Lücken sind, weil es keine Fehlerkorrektur oder Datenredundanz im pcm_u8 Datenstrom gibt, um die verlorenen Daten zu ermöglichen durch den AudioStream rekonstruiert werden.

Ich habe Dinge gesehen, wie VMWare absichtlich UDP-Pakete in einem virtuellen Netzwerk fallen lässt, um eine gute Leistung zu gewährleisten. Die Rechtfertigung ist, dass UDP nicht garantiert ist, dass die Lieferung sowieso "egal" ist. Das hat einen Kollegen, der RTP benutzt, schwer gestochen und eine garantierte Zustellung erwartet, aber nicht verstanden. Er hatte ein geschlossenes Netzwerksegment mit einem Server an jedem Ende der Leitung, von denen einer eine einzelne VM beherbergte.

Es könnte also einfach passieren, den Codec zu ändern, den Sie verwenden. Ich kann keinen empfehlen. Zunächst einmal lohnt es sich zu untersuchen, was ein Broadcast-Digital-Media-Stream verwendet. DVB-T verwendet MPEG Transport Stream (mit Fehlerkorrekturcodierung usw.) als AFAIK, ein Wrapper um MPEG-2.

Question

Ich würde gerne einen RTP-Audio-Stream hören, aber die Stimme hat kleine Lücken - nicht weiter. Was könnte die Lösung sein? Fehle ich etwas auf Empfänger (Android) Seite oder Streamer (ffmpeg) Seite?

Ich benutze ffmpeg um RTP Audio zu streamen,

ffmpeg -f lavfi -i aevalsrc="sin(400*2*PI*t)" -ar 8000 -vcodec pcm_u8 -f rtp rtp://192.168.0.15:41954 (port changes.)

Und hier ist mein verwandter Android-Code:

AudioStream audioStream;
AudioGroup audioGroup;
@Override
public void onStart() {
    super.onStart();
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitNetwork().build();
    StrictMode.setThreadPolicy(policy);
    AudioManager audio = (AudioManager)getSystemService(AUDIO_SERVICE);
    audio.setMode(AudioManager.MODE_IN_COMMUNICATION);
    audioGroup = new AudioGroup();
    audioGroup.setMode(AudioGroup.MODE_ECHO_SUPPRESSION);
    InetAddress inetAddress;
    try {
        inetAddress = InetAddress.getByName("192.168.0.15");
        audioStream = new AudioStream(inetAddress);
        audioStream.setCodec(AudioCodec.PCMU);
        audioStream.setMode(RtpStream.MODE_NORMAL);
        InetAddress inetAddressRemote = InetAddress.getByName("192.168.0.14");
        audioStream.associate(inetAddressRemote, 6000);
        ((TextView)findViewById(R.id.tv_port)).setText("Port : " + String.valueOf(audioStream.getLocalPort()));
        audioStream.join(audioGroup);
    }
    catch ( UnknownHostException e ) {
        e.printStackTrace();
    }
    catch ( SocketException e ) {
        e.printStackTrace();
    }
}