发布
社区首页 >问答首页 >接收RTP流- AudioStream、AudioGroup

接收RTP流- AudioStream、AudioGroup
EN

Stack Overflow用户
提问于 2014-12-03 18:13:57
回答 2查看 7.5K关注 0票数 22

我想听一个RTP音频流,但是声音中有很小的间隙-而不是继续。可能的解决方案是什么?我是不是在接收器(Android)端或Streamer(ffmpeg)端遗漏了什么?

我在用ffmpeg传输RTP音频,

代码语言:javascript
代码运行次数:0
复制
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.)

下面是我的相关android代码:

代码语言:javascript
代码运行次数:0
复制
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();
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-17 17:15:17

在回答我自己的问题时,问题出在android rtp包管理上。

安卓说,... assume packet interval is 50ms or less.AudioGroup source file上。

但是,RTP数据包的发送间隔为60ms。

这意味着50ms是不够的,这导致了下面描述的问题。

代码语言:javascript
代码运行次数:0
复制
Incoming: X X X X X X Y Y Y Y Y Y X X X X X X Y Y Y Y Y Y X X X X X X
Reading : X X X X X Y Y Y Y Y X X X X X Y Y Y Y Y X X X X X Y Y Y Y Y
          ^ ^ ^ ^ ^ - - - - - - - - - - - - - - - - - - - - ^ ^ ^ ^ ^ 
          ^                                                 ^
          |                                                 |
          |---- just these overlapping packets is valid ----|
          |---- and other packets discarding due to --------|
          |---- invalid RTP headers. -----------------------|

X, Y < packets

我每隔300ms只有一个包。这会产生抖动的声音。

我会为这个发送一个bug报告,希望它能帮助到一些人。

对于那些真正想听原始RTP流的人,我建议他们手动读取数据包,并将其解码为PCM16bit(这是android声卡支持的唯一音频格式),并将其写入AudioTrack。

票数 7
EN

Stack Overflow用户

发布于 2014-12-17 15:29:40

如果以下内容是愚蠢的,请道歉:

ffmpeg命令行似乎正在生成测试声音,并通过RTP将其作为pcm数据流发出。

RTP本身并不保证流数据的可靠传送,它只提供足够的信息来告诉接收器它是否接收到了所有数据,以及如果某些数据在传输过程中丢失,则确切地说丢失了哪些数据。另外,它通常在UDP上使用。

因此,对于RTP,重点在于RTP的用户发送以这种方式编码的数据(即,利用纠错编码、数据中的冗余等),以便接收器能够重建足够的原始数据以满足应用的需要。因此,对于音频流,您需要某种适合的编码格式。

我还没有找到pcm_u8是什么意思的参考资料,但它高度暗示它是一个简单的脉冲码调制数据流,具有8位数据。这听起来像没有任何纠错编码或数据冗余内置其中。丢失其中的一个字节意味着丢失一个样本,并且在接收端没有什么可以填充的。

所以我认为发生的情况是网络中的某些东西正在丢弃UDP数据包,RTP会告诉AudioStream丢失了哪些数据,结果是出现了间隙,因为pcm_u8数据流中没有纠错或数据冗余,因此AudioStream无法重建丢失的数据。

我见过像VMWare这样的东西故意在虚拟网络上丢弃UDP数据包,以确保良好的性能,理由是UDP无论如何都不能保证交付,所以“这无关紧要”。这严重刺痛了一位使用RTP的同事,他期待着有保证的交付,但却没有得到。他有一个封闭的网段,在线路的两端各有一台服务器,其中一台服务器托管一个虚拟机。

所以这可能只是一个改变你正在使用的编解码器的例子。我不能推荐一个。首先,有必要研究一下广播数字媒体流使用了什么。DVB-T使用MPEG传输流(具有纠错编码等)作为MPEG-2的包装器AFAIK。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27268928

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档