您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
8. 通过av_find_best_stream获取音视频流索引~1
发布时间:2021-05-31 14:57:36编辑:雪饮阅读()
日志貓沒有日志輸出問題
日志貓有時候有日志有時候沒有日志,這什麽情況?是不是usb調試鏈接太久了就會不發送日志了?
空空如也
實際上也還真有可能是這樣,此時,我在命令行執行”adb usb”命令后
android studio調試的設備來會重新變化一下,然後日志貓也change了,然後就會發現日志重新出來了。
獲取音頻流信息
同上次用for循環方式對比,這次獲取音視頻流信息要更簡潔,上次for循環的獲取方式實際上也是爲了找到音視頻流的索引。用av_find_best_stream方法就可以直接找到音視頻流的索引,自然也就比for循環方式能節省不少的代碼。
具體實例:cpp/native-lib.cpp:
#include <jni.h>
#include <string>
#include <android/log.h>
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,"testff",__VA_ARGS__)
extern "C"{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
}
static double r2d(AVRational r){
return r.num==0 | r.den==0 ? 0:(double) r.num/(double)r.den;
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_ndk_1and_141_MainActivity_stringFromJNI(JNIEnv* env,jobject) {
std::string hello = "Hello from C++";
hello+=avcodec_configuration();
//初始化解封裝
av_register_all();
//初始化網絡
avformat_network_init();
AVFormatContext *ic=NULL;
//要取一些信息,mp4格式取的比較多
char path[]="/sdcard/1080.mp4";
int re=avformat_open_input(&ic,path,0,0);
if(re!=0){
LOGW("avformat_open_input failed!:%s",av_err2str(re));
return env->NewStringUTF(hello.c_str());
}
/*
這裏需要漲點教訓,原來這裏是LOGW("avformat_open_input %s success!");
也就是多帶了一個%s,很明顯這裏語法在c中是有問題的,可是編譯過程時候沒有報錯。
日志貓中報錯信息讓我一度懷疑自己的arm64位動態鏈接庫編譯錯了呢。。。
*/
LOGW("avformat_open_input success!");
/*
duration方法:
mp4格式可以直接獲取到時長
返回類型是int64_t:
int64_t 是标准C ++类型,用于完全64位的有符号整数。 int64 不是标准类型。
第一个C ++标准没有固定宽度类型。在将 int64_t 添加到标准C ++之前,不同的编译器都实现了64位类型,但它们使用了自己的名称(例如 long long < / code>, __ int64 等。)
那麽因爲long long < / code>,所以這裏int64_t的輸出就是l ld了
*/
//對於flv來説,要先探測獲取下流信息,若不先探測,則獲取的場地可能就是如:-9223372036854775808一樣的負數
re=avformat_find_stream_info(ic,0);
if(re!=0){
LOGW("avformat_find_stream_info failed!");
}
//這裏格式化int64_t的時候千萬記住不是%lld而是%l ld
LOGW("duration=%l ld nb_streams=%d",ic->duration,ic->nb_streams);
int fps = 0;
int videoStream = 0;
int audioStream = 1;
/*
遍历获取AVStream音视频流信息并打印参数
*/
for(int i = 0; i < ic->nb_streams; i++)
{
AVStream *as = ic->streams[i];
if(as->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
LOGW("视频数据");
videoStream = i;
//avg_frame_rate:幀率,一個分數,就是fps的分數表示法,分數表示可以有效保護精度損失
fps = r2d(as->avg_frame_rate);
/*
codecpar->width,codecpar->height:视频的宽高,只有视频有
codecpar->codec_id: 獲取解碼器的id號
codecpar->format:格式。对于视频来说指的就是像素格式(YUV420,YUV422...),对于音频来说,指的就是音频的采样格式。
*/
LOGW("fps = %d,width=%d height=%d codeid=%d pixformat=%d",fps,
as->codecpar->width,
as->codecpar->height,
as->codecpar->codec_id,
as->codecpar->format
);
}
else if(as->codecpar->codec_type ==AVMEDIA_TYPE_AUDIO )
{
LOGW("音频数据");
audioStream = i;
/*
codecpar->sample_rate:樣本率
codecpar->channels:声道数
codecpar->format:格式。对于视频来说指的就是像素格式(YUV420,YUV422...),对于音频来说,指的就是音频的采样格式。
*/
LOGW("sample_rate=%d channels=%d sample_format=%d",
as->codecpar->sample_rate,
as->codecpar->channels,
as->codecpar->format
);
}
}
/*
獲取音頻流信息
第一個參數:AVStream的實例
第二個參數type:音頻或視頻流類型
第三個參數wanted_stream_nb是指定索引,這裏沒有必要,所以就為-1
第四個參數related_stream,同一節目組的相關流信息,這裏也沒有節目組,所以也就設置為-1
第五個參數decoder_ret 這個參數的作用我們要單獨做
第五個參數flags 目前還沒有用
*/
audioStream=av_find_best_stream(ic,AVMEDIA_TYPE_AUDIO,-1,-1,NULL,0);
LOGW("av_find_best_stream audioStream=%d",audioStream);
avformat_close_input(&ic);
return env->NewStringUTF(hello.c_str());
}
#include <string>
#include <android/log.h>
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,"testff",__VA_ARGS__)
extern "C"{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
}
static double r2d(AVRational r){
return r.num==0 | r.den==0 ? 0:(double) r.num/(double)r.den;
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_ndk_1and_141_MainActivity_stringFromJNI(JNIEnv* env,jobject) {
std::string hello = "Hello from C++";
hello+=avcodec_configuration();
//初始化解封裝
av_register_all();
//初始化網絡
avformat_network_init();
AVFormatContext *ic=NULL;
//要取一些信息,mp4格式取的比較多
char path[]="/sdcard/1080.mp4";
int re=avformat_open_input(&ic,path,0,0);
if(re!=0){
LOGW("avformat_open_input failed!:%s",av_err2str(re));
return env->NewStringUTF(hello.c_str());
}
/*
這裏需要漲點教訓,原來這裏是LOGW("avformat_open_input %s success!");
也就是多帶了一個%s,很明顯這裏語法在c中是有問題的,可是編譯過程時候沒有報錯。
日志貓中報錯信息讓我一度懷疑自己的arm64位動態鏈接庫編譯錯了呢。。。
*/
LOGW("avformat_open_input success!");
/*
duration方法:
mp4格式可以直接獲取到時長
返回類型是int64_t:
int64_t 是标准C ++类型,用于完全64位的有符号整数。 int64 不是标准类型。
第一个C ++标准没有固定宽度类型。在将 int64_t 添加到标准C ++之前,不同的编译器都实现了64位类型,但它们使用了自己的名称(例如 long long < / code>, __ int64 等。)
那麽因爲long long < / code>,所以這裏int64_t的輸出就是l ld了
*/
//對於flv來説,要先探測獲取下流信息,若不先探測,則獲取的場地可能就是如:-9223372036854775808一樣的負數
re=avformat_find_stream_info(ic,0);
if(re!=0){
LOGW("avformat_find_stream_info failed!");
}
//這裏格式化int64_t的時候千萬記住不是%lld而是%l ld
LOGW("duration=%l ld nb_streams=%d",ic->duration,ic->nb_streams);
int fps = 0;
int videoStream = 0;
int audioStream = 1;
/*
遍历获取AVStream音视频流信息并打印参数
*/
for(int i = 0; i < ic->nb_streams; i++)
{
AVStream *as = ic->streams[i];
if(as->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
LOGW("视频数据");
videoStream = i;
//avg_frame_rate:幀率,一個分數,就是fps的分數表示法,分數表示可以有效保護精度損失
fps = r2d(as->avg_frame_rate);
/*
codecpar->width,codecpar->height:视频的宽高,只有视频有
codecpar->codec_id: 獲取解碼器的id號
codecpar->format:格式。对于视频来说指的就是像素格式(YUV420,YUV422...),对于音频来说,指的就是音频的采样格式。
*/
LOGW("fps = %d,width=%d height=%d codeid=%d pixformat=%d",fps,
as->codecpar->width,
as->codecpar->height,
as->codecpar->codec_id,
as->codecpar->format
);
}
else if(as->codecpar->codec_type ==AVMEDIA_TYPE_AUDIO )
{
LOGW("音频数据");
audioStream = i;
/*
codecpar->sample_rate:樣本率
codecpar->channels:声道数
codecpar->format:格式。对于视频来说指的就是像素格式(YUV420,YUV422...),对于音频来说,指的就是音频的采样格式。
*/
LOGW("sample_rate=%d channels=%d sample_format=%d",
as->codecpar->sample_rate,
as->codecpar->channels,
as->codecpar->format
);
}
}
/*
獲取音頻流信息
第一個參數:AVStream的實例
第二個參數type:音頻或視頻流類型
第三個參數wanted_stream_nb是指定索引,這裏沒有必要,所以就為-1
第四個參數related_stream,同一節目組的相關流信息,這裏也沒有節目組,所以也就設置為-1
第五個參數decoder_ret 這個參數的作用我們要單獨做
第五個參數flags 目前還沒有用
*/
audioStream=av_find_best_stream(ic,AVMEDIA_TYPE_AUDIO,-1,-1,NULL,0);
LOGW("av_find_best_stream audioStream=%d",audioStream);
avformat_close_input(&ic);
return env->NewStringUTF(hello.c_str());
}
編譯部署並運行在如魅族16T上可以看到音視頻流的索引成功的獲取了。
关键字词:av_find_best_stream
相关文章
-
无相关信息