我在sdl_audio_callback 这里面拷贝了stream这个数据,并且另存为,但是这个数据不能播放。
[bilibili/ijkplayer]android怎么在播放的同时,提取PCM数据另存
回答
在 sdl_audio_callback 中是给 stream 中写入数据,在函数结束时把其中的数据保存就行了。肯定是可以播放的,但不能用播放器直接播放
:octocat: From gitme iOS
在 sdl_audio_callback 中是给 stream 中写入数据,在函数结束时把其中的数据保存就行了。肯定是可以播放的,但不能用播放器直接播放
:octocat: From gitme iOS 我就是在最末端拷贝数据的,结果播放不了,stream在写入数据的时候指针被修改了,我在写入数据前把stream备份了,然后按照len 传入的长度,对备份的stream数据进行拷贝。还是不行,另外我在 AudioTrack.c 这个文件中把J4AC_android_media_AudioTrack__write 函数的传参数据也保存下来了,同样不能播放。请问我的逻辑在哪个环节出错了。
贴代码吧,说不清楚
:octocat: From gitme iOS
/ prepare a new audio buffer / static void sdl_audio_callback(void opaque, Uint8 stream, int len) { Uint8 stream1=stream; FFPlayer ffp = opaque; VideoState *is = ffp->is; int audio_size, len1,len3; if (!ffp || !is) { memset(stream, 0, len); return; } len3=len; ffp->audio_callback_time = av_gettime_relative();
if (ffp->render_wait_start && !ffp->start_on_prepared && is->pause_req) {
while (is->pause_req && !is->abort_request) {
SDL_Delay(20);
}
}
.........省略 if(ffp->directBuff) { memcpy(ffp->directBuff, stream1, len3); ffp_notify_msg1(ffp, 30011); } }
描述:我把stream数组和len做了备份,反正数据在处理的时候变化,导致复制数据失败。ffp->directBuff,每次写入数据,都会用通知方法通知java层把directbuff数据写入到文件中去。 另外一个方案,我用的是代理方法,我在audiotrack类设置了代理,每次调用wirte方法,都会先走我得代理方法,这个代理方法的作用是把byte[] 数据复制写入到文件中去。这两种方法写入的文件,都不能播放。我很不解
贴代码吧,说不清楚
:octocat: From gitme iOS 代码已贴,中间多余的代码因为我没有去修改它,所以我省略了。你看这样粘贴可以吗
上面代码中 directbuff 是 c 代码中的内存数据, 怎么在 java 层写入文件去? 有点绕了。 可以直接 c 代码写文件。 audiotrack 方法代理应该没问题。
还有一点就是怎么播放的, 这种写到文件中没有媒体头信息,还得按照原来的声道采样率播放才行。
上面代码中 directbuff 是 c 代码中的内存数据, 怎么在 java 层写入文件去? 有点绕了。 可以直接 c 代码写文件。 audiotrack 方法代理应该没问题。
还有一点就是怎么播放的, 这种写到文件中没有媒体头信息,还得按照原来的声道采样率播放才行。 java 有一个DirectByteBuffer类,这个内存共享的,所以当收到通知java只要get一下就拿到字节数据了。因为我看见最后这些数据都是write audiotrack里面去,所以我把数据写入到文件中后,在用java代码读取出来,然后模拟ijkplayer的做法,256个字节的读取文件,write 自己创建的audiotrack实例中。结果两种方案保存的文件都不能正常播放。很不解
上面代码中 directbuff 是 c 代码中的内存数据, 怎么在 java 层写入文件去? 有点绕了。 可以直接 c 代码写文件。 audiotrack 方法代理应该没问题。
还有一点就是怎么播放的, 这种写到文件中没有媒体头信息,还得按照原来的声道采样率播放才行。 声道采样率,我对audiotrack设置了代理,所以监听到audiotrack所有的方法调用步奏和参数,采样率我感觉应该是一模一样的才对,但是结果很意外,ijkplayer调用audiotrack可以正常播放,我自己创建的audiotrack不能正常播放
你把保存的文件取出来 在电脑上用一些软件看能播放不
:octocat: From gitme iOS
你把保存的文件取出来 在电脑上用一些软件看能播放不
:octocat: From gitme iOS
不可以,很奇怪。我觉得我的思路没有毛病,但是实践起来就是不成功
你可以保存一段音频文件,发给我,我看看能不能播放。 告诉我采样率和声道数 @liwang0026 另外是不是多次把不同播放器的音频播放数据写到了一个文件中。
我在sdl_audio_callback这里面拷贝了stream这个数据,并且另存为,但是这个数据不能播放。
你好,我跟你遇到了同样的问题,我是在AudioTrack源码的write函数把音频流另存下来,但是另存下来的比原音频文件大好几倍,文件也没有媒体头信息
音频解码输出到硬件层之前,最终是调到pcm.c里的 int pcm_write(struct pcm pcm, const void data, unsigned int count) 接口 可以在这里面通过写文件的方式把音频pcm保存下来。 提取的pcm数据再添加一下头部信息组成.wav格式,可以正常播放。