转过去之后时间总是不对,于是我把avcodec_decode_audio4解码之后的源始文件直接保存为pcm格式的文件并用播放器进行播放,结果播放的速度快了一倍,播放器设置的采样率为44100,当我把它设为22050的时候时间相符了,而且播放也正常了。
我又看了下原始的mp4里的音频就是22050的采样率,我想如果能把22050的采样率转为44100的码率再转为mp2文件就应当正常了。ffmpeg里有提供方法进行转换吗?我试了用swr_convert方进行转换,好像还是不行。
还有个问题,我用avcodec_decode_audio4解出来的原始音频文件能直接用mp3lame转为mp3的格式吗?
8 个解决方案
#1
第一个问题,说明源是22.05KHz的音频,所以按照44.1KHz来播放,肯定是会有问题的。ffmpeg中的swr_convert就是用来做格式转换的,包括重采样。应该是可以的,你可以把你的代码贴出来看看。
第二个问题,avcodec_decode_audio4解出来的音频是否可以用mp3lame转mp3,要看mp3lame是否支持pcm这种没有描述的文件格式了,作为一个开源软件,我认为应该是支持的。
第二个问题,avcodec_decode_audio4解出来的音频是否可以用mp3lame转mp3,要看mp3lame是否支持pcm这种没有描述的文件格式了,作为一个开源软件,我认为应该是支持的。
#2
下面是我转码的代码,很乱,帮忙看看。我试了几个mp4的文件都有问题,如果源mp4是44100那它就变长变慢了,另一个mp4是22050,结果重采样之后本来是3分33秒的变成了1分59秒,但这1分59秒播放却很正常。1分59秒以后的就没了。我用一个播放器把转换出来的mp2文件用22050的采样率载入之后地却发现整首歌的音频都在。但播放声音变化很大,杂音也很大。是不是我重采样的参数有错误?
JNIEXPORT void JNICALL Java_com_example_ffmpegtest_Ffmpegs_isrun (JNIEnv * env , jobject obj) {
unsigned char *pEnCodeBuf = (char *)malloc(MAX_BUF_SIZE);
char *sourceFile = "/mnt/sdcard/test.mp4";
av_register_all();
/**
* 视频流解码部分
*/
//01 打开输入文件
if(avformat_open_input(&fmt_ctx , sourceFile , NULL , NULL)) {
LOGI("打开文件失败01");
return;
}
//02 取得流信息
if(avformat_find_stream_info(fmt_ctx , NULL) < 0) {
LOGI("取得流信息失败02");
return;
}
int s = fmt_ctx->nb_streams;
LOGI("nb_streams is %d" , s);
//return;
//03 判断流是否能正常打开
AVCodec *pInputCodec = NULL;
video_stream_idx = av_find_best_stream(fmt_ctx , AVMEDIA_TYPE_VIDEO , -1, -1, &pInputCodec, 0);
if(-1 == video_stream_idx)
{
//没有找到视频流
LOGI("没有找到视频流03");
return;
}
video_stream = fmt_ctx -> streams[video_stream_idx];
video_dec_ctx = video_stream->codec;
pInputCodec = avcodec_find_decoder(video_dec_ctx->codec_id);
if(NULL == pInputCodec)
{
//没有找到解码器
LOGI("没有找到解码器");
return;
}
LOGI("视频流是%d" , video_stream_idx);
if(avcodec_open2(video_dec_ctx , pInputCodec,NULL) != 0)
{
//打开解码器失败
LOGI("打开解码器失败");
return;
}
/**
* 音频流解码部分
*/
//03 判断流是否能正常打开
AVCodec *aupInputCodec = NULL;
int au_stream_idx = -1;
au_stream_idx = av_find_best_stream(fmt_ctx , AVMEDIA_TYPE_AUDIO, -1, -1, &aupInputCodec, 0);
if(-1 == au_stream_idx)
{
//没有找到视频流
LOGI("没有找到视频流03");
return;
}
audio_stream = fmt_ctx -> streams[au_stream_idx];
audio_dec_ctx = audio_stream->codec;
aupInputCodec = avcodec_find_decoder(audio_dec_ctx->codec_id);
if(NULL == pInputCodec)
{
//没有找到解码器
LOGI("没有找到解码器");
return;
}
if(avcodec_open2(audio_dec_ctx , aupInputCodec , NULL) != 0)
{
//打开解码器失败
LOGI("打开解码器失败");
return;
}
av_dump_format( fmt_ctx , -1 , sourceFile , 0);
/**
* 编码初始化
*/
AVFormatContext * outOc = NULL;
const char* filename = "/mnt/sdcard/testt.mp2";
AVOutputFormat *outFmt = NULL;
AVCodecContext *c = NULL;
AVCodec * outCodec;
if(avformat_alloc_output_context2(&outOc , NULL , NULL , filename) < 0){
LOGI("申请空间失败");
return;
}
outFmt = av_guess_format(NULL , filename , NULL);
if(NULL == outFmt){
LOGI("没有找到合适的容器");
return;
}
outCodec = avcodec_find_encoder(AV_CODEC_ID_MP2);
if(outCodec == NULL){
LOGI("没有找到mp2的编码器");
return;
}
c = avcodec_alloc_context3(outCodec);
c->sample_fmt = AV_SAMPLE_FMT_S16;
c->bit_rate = 64000;
c->sample_rate = 44100;
c->channels = 2;
c->channel_layout = AV_CH_LAYOUT_STEREO;
//c->bits_per_coded_sample = 2;
int avo = 5;
avo = avcodec_open2(c, outCodec, NULL);
if(avo < 0){
LOGI("打开编码器出错%d" , avo);
return;
}
AVStream * outSt = avformat_new_stream(outOc , outCodec);
if(NULL == outSt){
LOGI("没有找到合适的流");
return;
}
av_dump_format(outOc, 0, filename, 1);
outSt->id = 1;
/**
* 文件读取部分
*/
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
int isOk = -1;
int v = 0 , a = 0;
outFrame = avcodec_alloc_frame();
if(outFrame == NULL){
LOGI("frame分配内存失败");
return;
}
outFrame->nb_samples = c->frame_size;
outFrame->format = c->sample_fmt;
outFrame->channels = c->channels;
outFrame->channel_layout = c->channel_layout;
outFrame->linesize[0] = 2 * 4 * 44100 ;
outFrame->extended_data = outFrame->data[0] = av_malloc(outFrame->linesize[0]);
int outPktPts = 1;
AVPacket outPkt = {0};
int m_nAudioTimeStamp = 0;
int ao = 5;
ao = avio_open(&outOc->pb , filename , AVIO_FLAG_WRITE);
if(ao < 0){
LOGI("打开文件出错%d" , ao);
return;
}
int aw = 5;
avformat_write_header(outOc , NULL);
if(aw < 0){
LOGI("写文件头失败%d" , aw);
return;
}
double audio_pts;
AVFrame *frame = avcodec_alloc_frame();
uint8_t *pktdata;
int pktsize;
//重采样
struct SwrContext *swr_ctx ;
swr_ctx = swr_alloc();
if(!swr_ctx){
LOGI("sssssss");
return;
}
av_opt_set_int(swr_ctx, "in_channel_layout",audio_dec_ctx->channel_layout, 0);
av_opt_set_int(swr_ctx, "in_sample_rate", 22050, 0);
av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_FLTP , 0);
av_opt_set_int(swr_ctx, "out_channel_layout",c->channel_layout, 0);
av_opt_set_int(swr_ctx, "out_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
int wret = swr_init(swr_ctx);
if(wret < 0){
LOGI("I'm no");
return;
}
int mysize = 0;
int my = 0;
int ok = 0;
int64_t mypts = 0;
while(1) {
int got_frame = 0 , ret = 0 , got_packet_ptr = 5 , aa = 5;
isOk = av_read_frame(fmt_ctx, &pkt);
if(isOk >= 0) {
my++;
//视频处理
if(video_stream_idx == pkt.stream_index) {
v++;
}
//音频处理
if(au_stream_idx == pkt.stream_index) {
pktdata = pkt.data;
pktsize = pkt.size;
while(pktsize > 0){
ret = avcodec_decode_audio4(audio_dec_ctx, frame, &got_frame, &pkt);
if(ret < 0){
break;
}
pktsize -= ret;
pktdata += ret;
pkt.dts = pkt.pts = AV_NOPTS_VALUE;
if (got_frame) {
int wr = swr_convert(swr_ctx , outFrame->data , outFrame->nb_samples , (const uint8_t **)frame->data, frame->nb_samples);
outFrame->linesize[0] = frame->linesize[0];
av_init_packet(&outPkt);
outPkt.data = NULL;
outPkt.size = 0;
aa = avcodec_encode_audio2(c , &outPkt, outFrame , &got_packet_ptr);
outPkt.pts = av_rescale_q(outPkt.pts, c->time_base, outSt->time_base);
char ch[256];
av_strerror(aa , ch , 256);
if(aa < 0){
//LOGI("编成帧失败入");
}else{
//LOGI("编成帧成功");
outPkt.stream_index = outSt->index;
//outPkt.pts = pkt.pts;
av_interleaved_write_frame(outOc , &outPkt);
v++;
ok = 0;
}
a++;
}
}
}
} else {
LOGI("读完了");
break;
}
av_free_packet(&pkt);
}
av_write_trailer(outOc);
LOGI("成功 v = %d , a = %d , mysize = %d , my = %d" , v , a , mysize , my);
return;
}
JNIEXPORT void JNICALL Java_com_example_ffmpegtest_Ffmpegs_isrun (JNIEnv * env , jobject obj) {
unsigned char *pEnCodeBuf = (char *)malloc(MAX_BUF_SIZE);
char *sourceFile = "/mnt/sdcard/test.mp4";
av_register_all();
/**
* 视频流解码部分
*/
//01 打开输入文件
if(avformat_open_input(&fmt_ctx , sourceFile , NULL , NULL)) {
LOGI("打开文件失败01");
return;
}
//02 取得流信息
if(avformat_find_stream_info(fmt_ctx , NULL) < 0) {
LOGI("取得流信息失败02");
return;
}
int s = fmt_ctx->nb_streams;
LOGI("nb_streams is %d" , s);
//return;
//03 判断流是否能正常打开
AVCodec *pInputCodec = NULL;
video_stream_idx = av_find_best_stream(fmt_ctx , AVMEDIA_TYPE_VIDEO , -1, -1, &pInputCodec, 0);
if(-1 == video_stream_idx)
{
//没有找到视频流
LOGI("没有找到视频流03");
return;
}
video_stream = fmt_ctx -> streams[video_stream_idx];
video_dec_ctx = video_stream->codec;
pInputCodec = avcodec_find_decoder(video_dec_ctx->codec_id);
if(NULL == pInputCodec)
{
//没有找到解码器
LOGI("没有找到解码器");
return;
}
LOGI("视频流是%d" , video_stream_idx);
if(avcodec_open2(video_dec_ctx , pInputCodec,NULL) != 0)
{
//打开解码器失败
LOGI("打开解码器失败");
return;
}
/**
* 音频流解码部分
*/
//03 判断流是否能正常打开
AVCodec *aupInputCodec = NULL;
int au_stream_idx = -1;
au_stream_idx = av_find_best_stream(fmt_ctx , AVMEDIA_TYPE_AUDIO, -1, -1, &aupInputCodec, 0);
if(-1 == au_stream_idx)
{
//没有找到视频流
LOGI("没有找到视频流03");
return;
}
audio_stream = fmt_ctx -> streams[au_stream_idx];
audio_dec_ctx = audio_stream->codec;
aupInputCodec = avcodec_find_decoder(audio_dec_ctx->codec_id);
if(NULL == pInputCodec)
{
//没有找到解码器
LOGI("没有找到解码器");
return;
}
if(avcodec_open2(audio_dec_ctx , aupInputCodec , NULL) != 0)
{
//打开解码器失败
LOGI("打开解码器失败");
return;
}
av_dump_format( fmt_ctx , -1 , sourceFile , 0);
/**
* 编码初始化
*/
AVFormatContext * outOc = NULL;
const char* filename = "/mnt/sdcard/testt.mp2";
AVOutputFormat *outFmt = NULL;
AVCodecContext *c = NULL;
AVCodec * outCodec;
if(avformat_alloc_output_context2(&outOc , NULL , NULL , filename) < 0){
LOGI("申请空间失败");
return;
}
outFmt = av_guess_format(NULL , filename , NULL);
if(NULL == outFmt){
LOGI("没有找到合适的容器");
return;
}
outCodec = avcodec_find_encoder(AV_CODEC_ID_MP2);
if(outCodec == NULL){
LOGI("没有找到mp2的编码器");
return;
}
c = avcodec_alloc_context3(outCodec);
c->sample_fmt = AV_SAMPLE_FMT_S16;
c->bit_rate = 64000;
c->sample_rate = 44100;
c->channels = 2;
c->channel_layout = AV_CH_LAYOUT_STEREO;
//c->bits_per_coded_sample = 2;
int avo = 5;
avo = avcodec_open2(c, outCodec, NULL);
if(avo < 0){
LOGI("打开编码器出错%d" , avo);
return;
}
AVStream * outSt = avformat_new_stream(outOc , outCodec);
if(NULL == outSt){
LOGI("没有找到合适的流");
return;
}
av_dump_format(outOc, 0, filename, 1);
outSt->id = 1;
/**
* 文件读取部分
*/
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
int isOk = -1;
int v = 0 , a = 0;
outFrame = avcodec_alloc_frame();
if(outFrame == NULL){
LOGI("frame分配内存失败");
return;
}
outFrame->nb_samples = c->frame_size;
outFrame->format = c->sample_fmt;
outFrame->channels = c->channels;
outFrame->channel_layout = c->channel_layout;
outFrame->linesize[0] = 2 * 4 * 44100 ;
outFrame->extended_data = outFrame->data[0] = av_malloc(outFrame->linesize[0]);
int outPktPts = 1;
AVPacket outPkt = {0};
int m_nAudioTimeStamp = 0;
int ao = 5;
ao = avio_open(&outOc->pb , filename , AVIO_FLAG_WRITE);
if(ao < 0){
LOGI("打开文件出错%d" , ao);
return;
}
int aw = 5;
avformat_write_header(outOc , NULL);
if(aw < 0){
LOGI("写文件头失败%d" , aw);
return;
}
double audio_pts;
AVFrame *frame = avcodec_alloc_frame();
uint8_t *pktdata;
int pktsize;
//重采样
struct SwrContext *swr_ctx ;
swr_ctx = swr_alloc();
if(!swr_ctx){
LOGI("sssssss");
return;
}
av_opt_set_int(swr_ctx, "in_channel_layout",audio_dec_ctx->channel_layout, 0);
av_opt_set_int(swr_ctx, "in_sample_rate", 22050, 0);
av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_FLTP , 0);
av_opt_set_int(swr_ctx, "out_channel_layout",c->channel_layout, 0);
av_opt_set_int(swr_ctx, "out_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
int wret = swr_init(swr_ctx);
if(wret < 0){
LOGI("I'm no");
return;
}
int mysize = 0;
int my = 0;
int ok = 0;
int64_t mypts = 0;
while(1) {
int got_frame = 0 , ret = 0 , got_packet_ptr = 5 , aa = 5;
isOk = av_read_frame(fmt_ctx, &pkt);
if(isOk >= 0) {
my++;
//视频处理
if(video_stream_idx == pkt.stream_index) {
v++;
}
//音频处理
if(au_stream_idx == pkt.stream_index) {
pktdata = pkt.data;
pktsize = pkt.size;
while(pktsize > 0){
ret = avcodec_decode_audio4(audio_dec_ctx, frame, &got_frame, &pkt);
if(ret < 0){
break;
}
pktsize -= ret;
pktdata += ret;
pkt.dts = pkt.pts = AV_NOPTS_VALUE;
if (got_frame) {
int wr = swr_convert(swr_ctx , outFrame->data , outFrame->nb_samples , (const uint8_t **)frame->data, frame->nb_samples);
outFrame->linesize[0] = frame->linesize[0];
av_init_packet(&outPkt);
outPkt.data = NULL;
outPkt.size = 0;
aa = avcodec_encode_audio2(c , &outPkt, outFrame , &got_packet_ptr);
outPkt.pts = av_rescale_q(outPkt.pts, c->time_base, outSt->time_base);
char ch[256];
av_strerror(aa , ch , 256);
if(aa < 0){
//LOGI("编成帧失败入");
}else{
//LOGI("编成帧成功");
outPkt.stream_index = outSt->index;
//outPkt.pts = pkt.pts;
av_interleaved_write_frame(outOc , &outPkt);
v++;
ok = 0;
}
a++;
}
}
}
} else {
LOGI("读完了");
break;
}
av_free_packet(&pkt);
}
av_write_trailer(outOc);
LOGI("成功 v = %d , a = %d , mysize = %d , my = %d" , v , a , mysize , my);
return;
}
#3
outFrame->linesize[0] = frame->linesize[0];
这行代码有问题。你为什么这么写?
这行代码有问题。你为什么这么写?
#4
linesize[0]我查资料说是outFrame->data[0]的大小,但我试了,这行不写也是一样,我直接让它等0还是一样。我看我还是看看ffmepg.c是怎么写的算了。
#5
仅仅只是mark
#6
需要进行重采样,然后进行格式转换。。。。
#7
#8
http://blog.csdn.net/zhuweigangzwg/article/details/43733673 用ffmpeg实现音频resample(重采样)
#1
第一个问题,说明源是22.05KHz的音频,所以按照44.1KHz来播放,肯定是会有问题的。ffmpeg中的swr_convert就是用来做格式转换的,包括重采样。应该是可以的,你可以把你的代码贴出来看看。
第二个问题,avcodec_decode_audio4解出来的音频是否可以用mp3lame转mp3,要看mp3lame是否支持pcm这种没有描述的文件格式了,作为一个开源软件,我认为应该是支持的。
第二个问题,avcodec_decode_audio4解出来的音频是否可以用mp3lame转mp3,要看mp3lame是否支持pcm这种没有描述的文件格式了,作为一个开源软件,我认为应该是支持的。
#2
下面是我转码的代码,很乱,帮忙看看。我试了几个mp4的文件都有问题,如果源mp4是44100那它就变长变慢了,另一个mp4是22050,结果重采样之后本来是3分33秒的变成了1分59秒,但这1分59秒播放却很正常。1分59秒以后的就没了。我用一个播放器把转换出来的mp2文件用22050的采样率载入之后地却发现整首歌的音频都在。但播放声音变化很大,杂音也很大。是不是我重采样的参数有错误?
JNIEXPORT void JNICALL Java_com_example_ffmpegtest_Ffmpegs_isrun (JNIEnv * env , jobject obj) {
unsigned char *pEnCodeBuf = (char *)malloc(MAX_BUF_SIZE);
char *sourceFile = "/mnt/sdcard/test.mp4";
av_register_all();
/**
* 视频流解码部分
*/
//01 打开输入文件
if(avformat_open_input(&fmt_ctx , sourceFile , NULL , NULL)) {
LOGI("打开文件失败01");
return;
}
//02 取得流信息
if(avformat_find_stream_info(fmt_ctx , NULL) < 0) {
LOGI("取得流信息失败02");
return;
}
int s = fmt_ctx->nb_streams;
LOGI("nb_streams is %d" , s);
//return;
//03 判断流是否能正常打开
AVCodec *pInputCodec = NULL;
video_stream_idx = av_find_best_stream(fmt_ctx , AVMEDIA_TYPE_VIDEO , -1, -1, &pInputCodec, 0);
if(-1 == video_stream_idx)
{
//没有找到视频流
LOGI("没有找到视频流03");
return;
}
video_stream = fmt_ctx -> streams[video_stream_idx];
video_dec_ctx = video_stream->codec;
pInputCodec = avcodec_find_decoder(video_dec_ctx->codec_id);
if(NULL == pInputCodec)
{
//没有找到解码器
LOGI("没有找到解码器");
return;
}
LOGI("视频流是%d" , video_stream_idx);
if(avcodec_open2(video_dec_ctx , pInputCodec,NULL) != 0)
{
//打开解码器失败
LOGI("打开解码器失败");
return;
}
/**
* 音频流解码部分
*/
//03 判断流是否能正常打开
AVCodec *aupInputCodec = NULL;
int au_stream_idx = -1;
au_stream_idx = av_find_best_stream(fmt_ctx , AVMEDIA_TYPE_AUDIO, -1, -1, &aupInputCodec, 0);
if(-1 == au_stream_idx)
{
//没有找到视频流
LOGI("没有找到视频流03");
return;
}
audio_stream = fmt_ctx -> streams[au_stream_idx];
audio_dec_ctx = audio_stream->codec;
aupInputCodec = avcodec_find_decoder(audio_dec_ctx->codec_id);
if(NULL == pInputCodec)
{
//没有找到解码器
LOGI("没有找到解码器");
return;
}
if(avcodec_open2(audio_dec_ctx , aupInputCodec , NULL) != 0)
{
//打开解码器失败
LOGI("打开解码器失败");
return;
}
av_dump_format( fmt_ctx , -1 , sourceFile , 0);
/**
* 编码初始化
*/
AVFormatContext * outOc = NULL;
const char* filename = "/mnt/sdcard/testt.mp2";
AVOutputFormat *outFmt = NULL;
AVCodecContext *c = NULL;
AVCodec * outCodec;
if(avformat_alloc_output_context2(&outOc , NULL , NULL , filename) < 0){
LOGI("申请空间失败");
return;
}
outFmt = av_guess_format(NULL , filename , NULL);
if(NULL == outFmt){
LOGI("没有找到合适的容器");
return;
}
outCodec = avcodec_find_encoder(AV_CODEC_ID_MP2);
if(outCodec == NULL){
LOGI("没有找到mp2的编码器");
return;
}
c = avcodec_alloc_context3(outCodec);
c->sample_fmt = AV_SAMPLE_FMT_S16;
c->bit_rate = 64000;
c->sample_rate = 44100;
c->channels = 2;
c->channel_layout = AV_CH_LAYOUT_STEREO;
//c->bits_per_coded_sample = 2;
int avo = 5;
avo = avcodec_open2(c, outCodec, NULL);
if(avo < 0){
LOGI("打开编码器出错%d" , avo);
return;
}
AVStream * outSt = avformat_new_stream(outOc , outCodec);
if(NULL == outSt){
LOGI("没有找到合适的流");
return;
}
av_dump_format(outOc, 0, filename, 1);
outSt->id = 1;
/**
* 文件读取部分
*/
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
int isOk = -1;
int v = 0 , a = 0;
outFrame = avcodec_alloc_frame();
if(outFrame == NULL){
LOGI("frame分配内存失败");
return;
}
outFrame->nb_samples = c->frame_size;
outFrame->format = c->sample_fmt;
outFrame->channels = c->channels;
outFrame->channel_layout = c->channel_layout;
outFrame->linesize[0] = 2 * 4 * 44100 ;
outFrame->extended_data = outFrame->data[0] = av_malloc(outFrame->linesize[0]);
int outPktPts = 1;
AVPacket outPkt = {0};
int m_nAudioTimeStamp = 0;
int ao = 5;
ao = avio_open(&outOc->pb , filename , AVIO_FLAG_WRITE);
if(ao < 0){
LOGI("打开文件出错%d" , ao);
return;
}
int aw = 5;
avformat_write_header(outOc , NULL);
if(aw < 0){
LOGI("写文件头失败%d" , aw);
return;
}
double audio_pts;
AVFrame *frame = avcodec_alloc_frame();
uint8_t *pktdata;
int pktsize;
//重采样
struct SwrContext *swr_ctx ;
swr_ctx = swr_alloc();
if(!swr_ctx){
LOGI("sssssss");
return;
}
av_opt_set_int(swr_ctx, "in_channel_layout",audio_dec_ctx->channel_layout, 0);
av_opt_set_int(swr_ctx, "in_sample_rate", 22050, 0);
av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_FLTP , 0);
av_opt_set_int(swr_ctx, "out_channel_layout",c->channel_layout, 0);
av_opt_set_int(swr_ctx, "out_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
int wret = swr_init(swr_ctx);
if(wret < 0){
LOGI("I'm no");
return;
}
int mysize = 0;
int my = 0;
int ok = 0;
int64_t mypts = 0;
while(1) {
int got_frame = 0 , ret = 0 , got_packet_ptr = 5 , aa = 5;
isOk = av_read_frame(fmt_ctx, &pkt);
if(isOk >= 0) {
my++;
//视频处理
if(video_stream_idx == pkt.stream_index) {
v++;
}
//音频处理
if(au_stream_idx == pkt.stream_index) {
pktdata = pkt.data;
pktsize = pkt.size;
while(pktsize > 0){
ret = avcodec_decode_audio4(audio_dec_ctx, frame, &got_frame, &pkt);
if(ret < 0){
break;
}
pktsize -= ret;
pktdata += ret;
pkt.dts = pkt.pts = AV_NOPTS_VALUE;
if (got_frame) {
int wr = swr_convert(swr_ctx , outFrame->data , outFrame->nb_samples , (const uint8_t **)frame->data, frame->nb_samples);
outFrame->linesize[0] = frame->linesize[0];
av_init_packet(&outPkt);
outPkt.data = NULL;
outPkt.size = 0;
aa = avcodec_encode_audio2(c , &outPkt, outFrame , &got_packet_ptr);
outPkt.pts = av_rescale_q(outPkt.pts, c->time_base, outSt->time_base);
char ch[256];
av_strerror(aa , ch , 256);
if(aa < 0){
//LOGI("编成帧失败入");
}else{
//LOGI("编成帧成功");
outPkt.stream_index = outSt->index;
//outPkt.pts = pkt.pts;
av_interleaved_write_frame(outOc , &outPkt);
v++;
ok = 0;
}
a++;
}
}
}
} else {
LOGI("读完了");
break;
}
av_free_packet(&pkt);
}
av_write_trailer(outOc);
LOGI("成功 v = %d , a = %d , mysize = %d , my = %d" , v , a , mysize , my);
return;
}
JNIEXPORT void JNICALL Java_com_example_ffmpegtest_Ffmpegs_isrun (JNIEnv * env , jobject obj) {
unsigned char *pEnCodeBuf = (char *)malloc(MAX_BUF_SIZE);
char *sourceFile = "/mnt/sdcard/test.mp4";
av_register_all();
/**
* 视频流解码部分
*/
//01 打开输入文件
if(avformat_open_input(&fmt_ctx , sourceFile , NULL , NULL)) {
LOGI("打开文件失败01");
return;
}
//02 取得流信息
if(avformat_find_stream_info(fmt_ctx , NULL) < 0) {
LOGI("取得流信息失败02");
return;
}
int s = fmt_ctx->nb_streams;
LOGI("nb_streams is %d" , s);
//return;
//03 判断流是否能正常打开
AVCodec *pInputCodec = NULL;
video_stream_idx = av_find_best_stream(fmt_ctx , AVMEDIA_TYPE_VIDEO , -1, -1, &pInputCodec, 0);
if(-1 == video_stream_idx)
{
//没有找到视频流
LOGI("没有找到视频流03");
return;
}
video_stream = fmt_ctx -> streams[video_stream_idx];
video_dec_ctx = video_stream->codec;
pInputCodec = avcodec_find_decoder(video_dec_ctx->codec_id);
if(NULL == pInputCodec)
{
//没有找到解码器
LOGI("没有找到解码器");
return;
}
LOGI("视频流是%d" , video_stream_idx);
if(avcodec_open2(video_dec_ctx , pInputCodec,NULL) != 0)
{
//打开解码器失败
LOGI("打开解码器失败");
return;
}
/**
* 音频流解码部分
*/
//03 判断流是否能正常打开
AVCodec *aupInputCodec = NULL;
int au_stream_idx = -1;
au_stream_idx = av_find_best_stream(fmt_ctx , AVMEDIA_TYPE_AUDIO, -1, -1, &aupInputCodec, 0);
if(-1 == au_stream_idx)
{
//没有找到视频流
LOGI("没有找到视频流03");
return;
}
audio_stream = fmt_ctx -> streams[au_stream_idx];
audio_dec_ctx = audio_stream->codec;
aupInputCodec = avcodec_find_decoder(audio_dec_ctx->codec_id);
if(NULL == pInputCodec)
{
//没有找到解码器
LOGI("没有找到解码器");
return;
}
if(avcodec_open2(audio_dec_ctx , aupInputCodec , NULL) != 0)
{
//打开解码器失败
LOGI("打开解码器失败");
return;
}
av_dump_format( fmt_ctx , -1 , sourceFile , 0);
/**
* 编码初始化
*/
AVFormatContext * outOc = NULL;
const char* filename = "/mnt/sdcard/testt.mp2";
AVOutputFormat *outFmt = NULL;
AVCodecContext *c = NULL;
AVCodec * outCodec;
if(avformat_alloc_output_context2(&outOc , NULL , NULL , filename) < 0){
LOGI("申请空间失败");
return;
}
outFmt = av_guess_format(NULL , filename , NULL);
if(NULL == outFmt){
LOGI("没有找到合适的容器");
return;
}
outCodec = avcodec_find_encoder(AV_CODEC_ID_MP2);
if(outCodec == NULL){
LOGI("没有找到mp2的编码器");
return;
}
c = avcodec_alloc_context3(outCodec);
c->sample_fmt = AV_SAMPLE_FMT_S16;
c->bit_rate = 64000;
c->sample_rate = 44100;
c->channels = 2;
c->channel_layout = AV_CH_LAYOUT_STEREO;
//c->bits_per_coded_sample = 2;
int avo = 5;
avo = avcodec_open2(c, outCodec, NULL);
if(avo < 0){
LOGI("打开编码器出错%d" , avo);
return;
}
AVStream * outSt = avformat_new_stream(outOc , outCodec);
if(NULL == outSt){
LOGI("没有找到合适的流");
return;
}
av_dump_format(outOc, 0, filename, 1);
outSt->id = 1;
/**
* 文件读取部分
*/
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
int isOk = -1;
int v = 0 , a = 0;
outFrame = avcodec_alloc_frame();
if(outFrame == NULL){
LOGI("frame分配内存失败");
return;
}
outFrame->nb_samples = c->frame_size;
outFrame->format = c->sample_fmt;
outFrame->channels = c->channels;
outFrame->channel_layout = c->channel_layout;
outFrame->linesize[0] = 2 * 4 * 44100 ;
outFrame->extended_data = outFrame->data[0] = av_malloc(outFrame->linesize[0]);
int outPktPts = 1;
AVPacket outPkt = {0};
int m_nAudioTimeStamp = 0;
int ao = 5;
ao = avio_open(&outOc->pb , filename , AVIO_FLAG_WRITE);
if(ao < 0){
LOGI("打开文件出错%d" , ao);
return;
}
int aw = 5;
avformat_write_header(outOc , NULL);
if(aw < 0){
LOGI("写文件头失败%d" , aw);
return;
}
double audio_pts;
AVFrame *frame = avcodec_alloc_frame();
uint8_t *pktdata;
int pktsize;
//重采样
struct SwrContext *swr_ctx ;
swr_ctx = swr_alloc();
if(!swr_ctx){
LOGI("sssssss");
return;
}
av_opt_set_int(swr_ctx, "in_channel_layout",audio_dec_ctx->channel_layout, 0);
av_opt_set_int(swr_ctx, "in_sample_rate", 22050, 0);
av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_FLTP , 0);
av_opt_set_int(swr_ctx, "out_channel_layout",c->channel_layout, 0);
av_opt_set_int(swr_ctx, "out_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
int wret = swr_init(swr_ctx);
if(wret < 0){
LOGI("I'm no");
return;
}
int mysize = 0;
int my = 0;
int ok = 0;
int64_t mypts = 0;
while(1) {
int got_frame = 0 , ret = 0 , got_packet_ptr = 5 , aa = 5;
isOk = av_read_frame(fmt_ctx, &pkt);
if(isOk >= 0) {
my++;
//视频处理
if(video_stream_idx == pkt.stream_index) {
v++;
}
//音频处理
if(au_stream_idx == pkt.stream_index) {
pktdata = pkt.data;
pktsize = pkt.size;
while(pktsize > 0){
ret = avcodec_decode_audio4(audio_dec_ctx, frame, &got_frame, &pkt);
if(ret < 0){
break;
}
pktsize -= ret;
pktdata += ret;
pkt.dts = pkt.pts = AV_NOPTS_VALUE;
if (got_frame) {
int wr = swr_convert(swr_ctx , outFrame->data , outFrame->nb_samples , (const uint8_t **)frame->data, frame->nb_samples);
outFrame->linesize[0] = frame->linesize[0];
av_init_packet(&outPkt);
outPkt.data = NULL;
outPkt.size = 0;
aa = avcodec_encode_audio2(c , &outPkt, outFrame , &got_packet_ptr);
outPkt.pts = av_rescale_q(outPkt.pts, c->time_base, outSt->time_base);
char ch[256];
av_strerror(aa , ch , 256);
if(aa < 0){
//LOGI("编成帧失败入");
}else{
//LOGI("编成帧成功");
outPkt.stream_index = outSt->index;
//outPkt.pts = pkt.pts;
av_interleaved_write_frame(outOc , &outPkt);
v++;
ok = 0;
}
a++;
}
}
}
} else {
LOGI("读完了");
break;
}
av_free_packet(&pkt);
}
av_write_trailer(outOc);
LOGI("成功 v = %d , a = %d , mysize = %d , my = %d" , v , a , mysize , my);
return;
}
#3
outFrame->linesize[0] = frame->linesize[0];
这行代码有问题。你为什么这么写?
这行代码有问题。你为什么这么写?
#4
linesize[0]我查资料说是outFrame->data[0]的大小,但我试了,这行不写也是一样,我直接让它等0还是一样。我看我还是看看ffmepg.c是怎么写的算了。
#5
仅仅只是mark
#6
需要进行重采样,然后进行格式转换。。。。
#7
#8
http://blog.csdn.net/zhuweigangzwg/article/details/43733673 用ffmpeg实现音频resample(重采样)