translate audio_player.c into English

translate audio_player.c into English
pull/166/head
xufulong 5 years ago
parent c99305147c
commit 8922e50150
  1. 3
      app/src/main/cpp/audio_lame.c
  2. 148
      app/src/main/cpp/audio_player.c

@ -190,7 +190,8 @@ AUDIO_PLAYER_FUNC(void, lameInit,
jint inSampleRate, jint outChannel, jint outSampleRate, jint outBitrate,
jfloat scaleInput, jint mode, jint vbrMode, jint quality, jint vbrQuality,
jint abrMeanBitrate, jint lowPassFreq, jint highPassFreq, jstring id3tagTitle,
jstring id3tagArtist, jstring id3tagAlbum, jstring id3tagYear, jstring id3tagComment) {
jstring id3tagArtist, jstring id3tagAlbum, jstring id3tagYear,
jstring id3tagComment) {
glf = initialize(env, inSampleRate, outChannel, outSampleRate, outBitrate, scaleInput, mode,
vbrMode,

@ -4,15 +4,12 @@
#include <jni.h>
#include <stdlib.h>
#include <unistd.h>
//封装格式
#include <android/log.h>
#include "libavformat/avformat.h"
//解码
#include "libavcodec/avcodec.h"
//缩放
#include "libswscale/swscale.h"
//重采样
#include "libswresample/swresample.h"
#include <android/log.h>
#include "ffmpeg_jni_define.h"
#define TAG "AudioPlayer"
@ -20,122 +17,127 @@
#define MAX_AUDIO_FRAME_SIZE 48000 * 4
AUDIO_PLAYER_FUNC(void, play, jstring input_jstr) {
const char* input_cstr = (*env)->GetStringUTFChars(env,input_jstr,NULL);
const char *input_cstr = (*env)->GetStringUTFChars(env, input_jstr, NULL);
LOGI(TAG, "input_cstr=%s", input_cstr);
//注册组件
//register all modules
av_register_all();
AVFormatContext *pFormatCtx = avformat_alloc_context();
//打开音频文件
if(avformat_open_input(&pFormatCtx,input_cstr,NULL,NULL) != 0){
LOGE(TAG, "无法打开音频文件");
//open the audio file
if (avformat_open_input(&pFormatCtx, input_cstr, NULL, NULL) != 0) {
LOGE(TAG, "Couldn't open the audio file!");
return;
}
//获取输入文件信息
if(avformat_find_stream_info(pFormatCtx,NULL) < 0){
LOGE(TAG, "无法获取输入文件信息");
//find all streams info
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
LOGE(TAG, "Couldn't find stream info!");
return;
}
//获取音频流索引位置
//get the audio stream index in the stream array
int i = 0, audio_stream_idx = -1;
for(; i < pFormatCtx->nb_streams;i++){
if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO){
for (; i < pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
audio_stream_idx = i;
break;
}
}
//获取音频解码器
//find audio decoder
AVCodecContext *codecCtx = pFormatCtx->streams[audio_stream_idx]->codec;
AVCodec *codec = avcodec_find_decoder(codecCtx->codec_id);
if(codec == NULL){
LOGE(TAG, "无法获取解码器");
if (codec == NULL) {
LOGE(TAG, "Couldn't find audio decoder!");
return;
}
//打开解码器
if(avcodec_open2(codecCtx,codec,NULL) < 0){
LOGE(TAG, "无法打开解码器");
//open audio decoder
if (avcodec_open2(codecCtx, codec, NULL) < 0) {
LOGE(TAG, "Couldn't open audio decoder");
return;
}
//压缩数据
AVPacket *packet = (AVPacket *)av_malloc(sizeof(AVPacket));
//解压缩数据
//malloc packet memory
AVPacket *packet = (AVPacket *) av_malloc(sizeof(AVPacket));
//malloc frame memory
AVFrame *frame = av_frame_alloc();
//frame->16bit 44100 PCM 统一音频采样格式与采样率
//frame->16bit 44100 PCM
SwrContext *swrCtx = swr_alloc();
//输入的采样格式
//input sampleFormat
enum AVSampleFormat in_sample_fmt = codecCtx->sample_fmt;
//输出采样格式16bit PCM
//output sampleFormat: 16bit PCM
enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16;
//输入采样率
//input sampleRate
int in_sample_rate = codecCtx->sample_rate;
//输出采样率
//output sampleRate
int out_sample_rate = in_sample_rate;
//声道布局(2个声道,默认立体声stereo)
//input channel layout(2 channels, stereo by default)
uint64_t in_ch_layout = codecCtx->channel_layout;
//输出的声道布局(立体声)
//output channel layout
uint64_t out_ch_layout = AV_CH_LAYOUT_STEREO;
swr_alloc_set_opts(swrCtx,
out_ch_layout,out_sample_fmt,out_sample_rate,
in_ch_layout,in_sample_fmt,in_sample_rate,
out_ch_layout, out_sample_fmt, out_sample_rate,
in_ch_layout, in_sample_fmt, in_sample_rate,
0, NULL);
swr_init(swrCtx);
//输出的声道个数
//output channel number
int out_channel_nb = av_get_channel_layout_nb_channels(out_ch_layout);
jclass player_class = (*env)->GetObjectClass(env,thiz);
if(!player_class){
jclass player_class = (*env)->GetObjectClass(env, thiz);
if (!player_class) {
LOGE(TAG, "player_class not found...");
}
//AudioTrack对象
jmethodID audio_track_method = (*env)->GetMethodID(env,player_class,"createAudioTrack","(II)Landroid/media/AudioTrack;");
if(!audio_track_method){
//get AudioTrack by reflection
jmethodID audio_track_method = (*env)->GetMethodID(env, player_class, "createAudioTrack",
"(II)Landroid/media/AudioTrack;");
if (!audio_track_method) {
LOGE(TAG, "audio_track_method not found...");
}
jobject audio_track = (*env)->CallObjectMethod(env,thiz,audio_track_method,out_sample_rate,out_channel_nb);
jobject audio_track = (*env)->CallObjectMethod(env, thiz, audio_track_method, out_sample_rate,
out_channel_nb);
//调用play方法
jclass audio_track_class = (*env)->GetObjectClass(env,audio_track);
jmethodID audio_track_play_mid = (*env)->GetMethodID(env,audio_track_class,"play","()V");
(*env)->CallVoidMethod(env,audio_track,audio_track_play_mid);
//call play method
jclass audio_track_class = (*env)->GetObjectClass(env, audio_track);
jmethodID audio_track_play_mid = (*env)->GetMethodID(env, audio_track_class, "play", "()V");
(*env)->CallVoidMethod(env, audio_track, audio_track_play_mid);
//获取write()方法
jmethodID audio_track_write_mid = (*env)->GetMethodID(env,audio_track_class,"write","([BII)I");
//get write method
jmethodID audio_track_write_mid = (*env)->GetMethodID(env, audio_track_class, "write",
"([BII)I");
//16bit 44100 PCM 数据
uint8_t *out_buffer = (uint8_t *)av_malloc(MAX_AUDIO_FRAME_SIZE);
uint8_t *out_buffer = (uint8_t *) av_malloc(MAX_AUDIO_FRAME_SIZE);
int got_frame = 0,index = 0, ret;
//不断读取编码数据
while(av_read_frame(pFormatCtx,packet) >= 0){
//解码音频类型的Packet
if(packet->stream_index == audio_stream_idx){
//解码
ret = avcodec_decode_audio4(codecCtx,frame,&got_frame,packet);
if(ret < 0){
int got_frame = 0, index = 0, ret;
//read audio frame
while (av_read_frame(pFormatCtx, packet) >= 0) {
//is audio stream index
if (packet->stream_index == audio_stream_idx) {
//do decode
ret = avcodec_decode_audio4(codecCtx, frame, &got_frame, packet);
if (ret < 0) {
break;
}
//解码一帧成功
if(got_frame > 0){
//decode success
if (got_frame > 0) {
LOGI(TAG, "decode frame count=%d", index++);
//音频格式转换
swr_convert(swrCtx, &out_buffer, MAX_AUDIO_FRAME_SIZE,(const uint8_t **)frame->data,frame->nb_samples);
//convert audio format
swr_convert(swrCtx, &out_buffer, MAX_AUDIO_FRAME_SIZE,
(const uint8_t **) frame->data, frame->nb_samples);
int out_buffer_size = av_samples_get_buffer_size(NULL, out_channel_nb,
frame->nb_samples, out_sample_fmt, 1);
frame->nb_samples, out_sample_fmt,
1);
jbyteArray audio_sample_array = (*env)->NewByteArray(env,out_buffer_size);
jbyte* sample_byte_array = (*env)->GetByteArrayElements(env,audio_sample_array,NULL);
//拷贝缓冲数据
jbyteArray audio_sample_array = (*env)->NewByteArray(env, out_buffer_size);
jbyte *sample_byte_array = (*env)->GetByteArrayElements(env, audio_sample_array,
NULL);
//copy buffer data
memcpy(sample_byte_array, out_buffer, (size_t) out_buffer_size);
//释放数组
(*env)->ReleaseByteArrayElements(env,audio_sample_array,sample_byte_array,0);
//调用AudioTrack的write方法进行播放
(*env)->CallIntMethod(env,audio_track,audio_track_write_mid,
audio_sample_array,0,out_buffer_size);
//释放局部引用
(*env)->DeleteLocalRef(env,audio_sample_array);
//release byteArray
(*env)->ReleaseByteArrayElements(env, audio_sample_array, sample_byte_array, 0);
//call write method to play
(*env)->CallIntMethod(env, audio_track, audio_track_write_mid,
audio_sample_array, 0, out_buffer_size);
//delete local reference
(*env)->DeleteLocalRef(env, audio_sample_array);
usleep(1000 * 16);
}
}
@ -147,6 +149,6 @@ AUDIO_PLAYER_FUNC(void, play, jstring input_jstr) {
swr_free(&swrCtx);
avcodec_close(codecCtx);
avformat_close_input(&pFormatCtx);
(*env)->ReleaseStringUTFChars(env,input_jstr,input_cstr);
(*env)->ReleaseStringUTFChars(env, input_jstr, input_cstr);
}
Loading…
Cancel
Save