【问题标题】:Play mp3 data with audiotrack with ffmpeg使用 ffmpeg 播放带有音轨的 mp3 数据
【发布时间】:2014-01-31 12:20:25
【问题描述】:

我正在设计一个 android 应用程序,我在其中接收来自 Red5 服务器的实时 mp3 数据流,我需要播放它。

我无法使用媒体播放器类播放它,因为我没有任何流的 url,也无法使用文件。另一种选择是使用音频轨道类,但只需要 PCM 数据。所以需要将mp3转为pcm,所以使用ffmpeg。

我的转换代码是

AVCodec *codec;
AVCodecContext *c= NULL;
int out_size, len;
uint8_t *outbuf;

int iplen=(*env)->GetArrayLength(env, mp3buf);
int16_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
AVPacket avpkt;
av_init_packet(&avpkt);
av_register_all();
avcodec_register_all();

codec = avcodec_find_decoder(CODEC_ID_MP3);
if(!codec){
    __android_log_print(ANDROID_LOG_DEBUG, "logfromjni", "Codec not found");
}
c = avcodec_alloc_context();
outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
avpkt.data = (*env)->GetByteArrayElements(env,mp3buf,NULL);

avpkt.size = (*env)->GetArrayLength(env, mp3buf);
out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
int ao=avcodec_open(c, codec);
    if (ao < 0) {
        __android_log_print(ANDROID_LOG_DEBUG, "logfromjni", "avcodec not open");
    }
    len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &avpkt);

问题是avcodec_decode_audio3(c, (short *)outbuf, &amp;out_size, &amp;avpkt); 总是返回-1。

不知道怎么回事。

任何帮助表示赞赏。

【问题讨论】:

  • 要查找错误原因,请尝试查看 ffmpeg 输出。如果在设备上很难做到,您可以重定向 ffmpeg 输出并通过自己的回调执行日志记录(参见av_log_set_callbackav_log_set_level

标签: android ffmpeg java-native-interface audiotrack


【解决方案1】:

MP3 是一种基于帧的格式,因此您需要将完整的帧传递给 decode_audio3 以使其产生有意义的结果。它不像 zlib,您可以使用任何大小(甚至 1 个字节)的数据块并最终获得一些输出。确保:

  • 您的服务器以正确的帧发送数据;
  • 您在客户端正确处理这些帧(请记住,来自服务器的两个 2kb send() 不会在 recv() 中产生两个 2kb 块,而是在一个 4kb 块中);
  • 您将完整的块传递给 decode_audio3。

【讨论】:

  • 我想我可能会遇到完整帧的问题,知道如何确保帧有效,或者收到完整的块..
  • 从服务器大小发送块时,首先发送帧长度(以 DWORD 形式),然后发送帧内容。这样,您将始终知道客户端是否收到了整个帧。
猜你喜欢
  • 1970-01-01
  • 2013-11-11
  • 1970-01-01
  • 2011-06-27
  • 1970-01-01
  • 2011-01-07
  • 1970-01-01
  • 1970-01-01
  • 2011-07-26
相关资源
最近更新 更多