- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试在 android 中使用 ffmpeg 播放音频 mp3 文件但是我在下面提到的代码中遇到了问题
如何使用ffmpeg播放mp3
void JNICALL Java_com_music_MainActivity_loadFile(JNIEnv* env, jobject obj,jstring file,jbyteArray array)
{
jboolean isfilenameCopy;
const char * filename = (*env)->GetStringUTFChars(env, file, &isfilenameCopy);
AVCodec *codec;
AVCodecContext *c= NULL;
int out_size, len;
FILE *f, *outfile;
uint8_t *outbuf;
uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
AVPacket avpkt;
jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID play = (*env)->GetMethodID(env, cls, "playSound", "([BI)V");//At the begining of your main function
av_init_packet(&avpkt);
printf("Audio decoding\n");
__android_log_print(ANDROID_LOG_INFO, DEBUG_TAG, "inside load file");
/* find the mpeg audio decoder */
codec = avcodec_find_decoder(CODEC_ID_MP3);
if (!codec) {
fprintf(stderr, "codec not found\n");
exit(1);
}
c= avcodec_alloc_context();
/* open it */
if (avcodec_open(c, codec) < 0) {
fprintf(stderr, "could not open codec\n");
exit(1);
}
__android_log_print(ANDROID_LOG_INFO, DEBUG_TAG, "open avcode");
outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
__android_log_print(ANDROID_LOG_INFO, DEBUG_TAG, "open %s",outbuf);
f = fopen(filename, "rb");
if (!f) {
fprintf(stderr, "could not open %s\n", filename);
exit(1);
}
/* decode until eof */
avpkt.data = inbuf;
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
__android_log_print(ANDROID_LOG_INFO, DEBUG_TAG, "data =%s and size %d",avpkt.data,avpkt.size);
while (avpkt.size > 0) {
out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &avpkt);
__android_log_print(ANDROID_LOG_INFO, DEBUG_TAG, "length =%d",len);
if (len < 0) {
fprintf(stderr, "Error while decoding\n");
__android_log_print(ANDROID_LOG_INFO, DEBUG_TAG, " failed length =%d",errno);
exit(1);
}
if (out_size > 0) {
/* if a frame has been decoded, output it */
jbyte *bytes = (*env)->GetByteArrayElements(env, array, NULL);
memcpy(bytes, outbuf, out_size); //
(*env)->ReleaseByteArrayElements(env, array, bytes, 0);
(*env)->CallVoidMethod(env, obj, play, array, out_size);
}
avpkt.size -= len;
avpkt.data += len;
if (avpkt.size < AUDIO_REFILL_THRESH) {
/* Refill the input buffer, to avoid trying to decode
* incomplete frames. Instead of this, one could also use
* a parser, or use a proper container format through
* libavformat. */
memmove(inbuf, avpkt.data, avpkt.size);
avpkt.data = inbuf;
len = fread(avpkt.data + avpkt.size, 1,
AUDIO_INBUF_SIZE - avpkt.size, f);
if (len > 0)
avpkt.size += len;
}
}
fclose(f);
free(outbuf);
avcodec_close(c);
av_free(c);
}
我得到 len = - 1
len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &avpkt);
我做错了什么??
请帮忙
最佳答案
void JNICALL Java_com_music_MainActivity_loadFile(JNIEnv* env, jobject obj,jstring file,jbyteArray array)
{
jboolean isCopy;
int i;
int err;
FILE *f, *outfile;
int audioStream=-1;
int res;
int decoded = 0;
int out_size;
AVFrame *frame = av_frame_alloc();
int got_frame;
uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID play = (*env)->GetMethodID(env, cls, "playSound", "([BI)V");//At the begining of your main function
const char * szfile = (*env)->GetStringUTFChars(env, file, &isCopy);
LOGI("in load file");
if ((ret = avformat_open_input(&fmt_ctx, szfile, NULL, NULL)) < 0)
{
LOGE("Cannot open input file\n");
}
LOGE("file load %s\n",szfile);
if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0)
{
LOGE("Cannot find stream information\n");
}
/* select the audio stream */
ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0);
if (ret < 0)
{
LOGE("Cannot find a audio stream in the input file\n");
}
// timeBase = (int64_t(aCodecCtx->time_base.num) * AV_TIME_BASE) / int64_t(aCodecCtx->time_base.den);
audio_stream_index = ret;
dec_ctx = fmt_ctx->streams[audio_stream_index]->codec;
av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0);
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0)
{
LOGE("Cannot open audio decoder\n");
}
dec_ctx->sample_fmt =AV_SAMPLE_FMT_S16
dec_ctx->codec_id = AV_CODEC_ID_AAC;
f = fopen(szfile, "rb");
if (!f)
{
LOGE("could not open");
exit(1);
}
// LOGE("time of frame %d",aCodecCtx->time_base.num);
// av_seek_frame();
// timeBase =(aCodecCtx->time_base.num *AV_TIME_BASE)/(aCodecCtx->time_base.den);
// LOGE("time of frame %d",aCodecCtx->time_base.den);
LOGE("time of frame %d",timeBase);
packet.data = inbuf;
packet.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
LOGE("Stage 5");
while (1)
{
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
break;
if (packet.stream_index == audio_stream_index)
{
avcodec_get_frame_defaults(frame);
got_frame = 0;
ret = avcodec_decode_audio4(dec_ctx, frame, &got_frame, &packet);
LOGE("len=%d",ret);
if (ret < 0)
{
LOGE("Error decoding audio\n");
continue;
}
if (got_frame)
{
LOGE("begin frame decode\n");
int data_size = av_samples_get_buffer_size(NULL, dec_ctx->channels,frame->nb_samples,dec_ctx->sample_fmt, 1);
LOGE("after frame decode\n");
jbyte *bytes = (*env)->GetByteArrayElements(env, array, NULL);
memcpy(bytes, frame->data[0], data_size); //
(*env)->ReleaseByteArrayElements(env, array, bytes, 0);
(*env)->CallVoidMethod(env, obj, play, array, data_size);
}
packet.size -= ret;
packet.data += ret;
packet.pts = AV_NOPTS_VALUE;
if (packet.size < AUDIO_REFILL_THRESH)
{
memmove(inbuf, packet.data, packet.size);
packet.data = inbuf;
ret = fread(packet.data + packet.size, 1, AUDIO_INBUF_SIZE - packet.size, f);
if (ret > 0)
packet.size += ret;
}
}
}
av_free_packet(&packet);
}
尝试这段代码我做了一些改变现在它工作正常
关于android - 如何使用 ffmpeg 播放 mp3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19704351/
我正在使用以下代码播放声音,过一会儿它将停止播放声音,这是因为我相信有太多的Mediaplayer打开实例,所以我添加了一个额外的mp.release();,这只会使我的应用程序崩溃(目前已被注释掉)
我正在查看 XV-6 代码,它通过它识别 MP 结构。它首先在 EBDA 的第一个 kb 中搜索。代码是这样的 static struct mp* mpsearch(void) { uchar *
我在我的应用程序中使用 Mp 饼图。它显示非常小的尺寸,我试图增加它的尺寸但它没有增加它的尺寸。我无法找出问题所在。请告诉我们如何增加尺寸。 这是我的代码: public class MPpiecha
如何使用 MPAndroidChart 实现此目的? 使用版本:com.github.PhilJay:MPAndroidChart:v3.1.0-alpha 添加图例和饼图边距的代码: private
亲爱的社区,我面临以下问题,我正在使用此处提供的 MP android 图表库创建条形图:https://github.com/PhilJay/MPAndroidChart . 我想为我的条设置渐变背
我正在使用 SAS MP Connect 开发我的第一段代码,以运行同一个 sas 作业的并行线程。 我知道 MP CONNECT 仅受可用 CPU 数量的物理限制,但理想情况下我不想在我的工作中使用
我最近购买了在 Linux 服务器上运行的 Stata MP12(8 核)许可证。 有没有人写过 Stata 程序,比如说模拟研究来测试 Stata MP 的性能?我想监视在作业处理过程中实际使用的内
我将不胜感激任何“一步一步”指南,说明如何更改 PHP/HTML 页面上的动态数据库连接/连接字符串/等上的代码,使其“即插即用”工作通过 ftp 将页面和 MySQL 数据库托管在“Azure 网站
试图在我的应用程序中放置一个“暂停”按钮,以播放一些声音片段循环播放。 当我打电话mp.pause();一切都破了,我完全迷路了! 这是我正在使用的方法。 protected void man
我想使用 Mp Chart 创建折线图 我想要实现的是这张图片 但是到目前为止我已经得到了这个。 我使用的代码是这个 private fun setData() { val entries
通常,我可能会编写一个类似simd的循环: float * x = (float *) malloc(10 * sizeof(float)); float * y = (float *) malloc
在与堆栈空间、OpenMP 以及如何处理这些问题相关的其他帖子上,有很多回复。但是,我找不到信息来真正理解 OpenMP 调整编译器选项的原因: 原因是什么-fopenmp在 gfortran 中暗示
我有一段代码,可以根据漂移、波动性和随机数计算任意给定日期的股票价格。但是当我检查输出列表时 - 它们是算术级数,而不是几何级数(幂函数)。我共享的变量有问题吗? 代码如下: #include #i
我正在尝试在 C++11 中并行化动态编程算法使用这种方法: void buildBaseCases() { cout << "Building base cases" << endl
我正在 open MP 中实现并行点积 我有这个代码: #include #include #include #include #include #include #define SIZE
我有一台服务器已经将近 4 年了,直到现在我都没有遇到任何问题(主机端)。我一直在更换主机,因为 ddos 的东西试图找到最适合我的东西。现在我买了一个 VPS(这不是我的第一个)并尝试运行我的服
所以我有两个内部平行区域的外部平行区域。是否可以将 2 个线程放入外部平行线,将 4 个线程放入每个内部平行线?我做了这样的东西,但它似乎无法按照我想要的方式工作。有什么建议吗? start_r =
我希望有人指出我们遇到的问题或解决方法。 使用/MP 编译项目时,似乎只有同一文件夹中的文件会同时编译。我使用 Process Explorer 滑动命令行并确认行为。 项目过滤器似乎对并发编译的内容
本文整理了Java中me.chanjar.weixin.mp.api.WxMpMessageRouter类的一些代码示例,展示了WxMpMessageRouter类的具体用法。这些代码示例主要来源于G
我正在监视 Stata/MP(Stata/SE 的多核版本)的 CPU 和内存使用情况,但我不是 Stata 程序员(更像是 Perl 人)。 任何人都可以发布一些代码,利用公共(public)数据集
我是一名优秀的程序员,十分优秀!