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. 90
      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"
@ -22,20 +19,20 @@
AUDIO_PLAYER_FUNC(void, play, jstring input_jstr) {
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();
//打开音频文件
//open the audio file
if (avformat_open_input(&pFormatCtx, input_cstr, NULL, NULL) != 0) {
LOGE(TAG, "无法打开音频文件");
LOGE(TAG, "Couldn't open the audio file!");
return;
}
//获取输入文件信息
//find all streams info
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
LOGE(TAG, "无法获取输入文件信息");
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) {
@ -44,36 +41,36 @@ AUDIO_PLAYER_FUNC(void, play, jstring input_jstr) {
}
}
//获取音频解码器
//find audio decoder
AVCodecContext *codecCtx = pFormatCtx->streams[audio_stream_idx]->codec;
AVCodec *codec = avcodec_find_decoder(codecCtx->codec_id);
if (codec == NULL) {
LOGE(TAG, "无法获取解码器");
LOGE(TAG, "Couldn't find audio decoder!");
return;
}
//打开解码器
//open audio decoder
if (avcodec_open2(codecCtx, codec, NULL) < 0) {
LOGE(TAG, "无法打开解码器");
LOGE(TAG, "Couldn't open audio decoder");
return;
}
//压缩数据
//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,
@ -82,59 +79,64 @@ AUDIO_PLAYER_FUNC(void, play, jstring input_jstr) {
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) {
LOGE(TAG, "player_class not found...");
}
//AudioTrack对象
jmethodID audio_track_method = (*env)->GetMethodID(env,player_class,"createAudioTrack","(II)Landroid/media/AudioTrack;");
//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方法
//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);
int got_frame = 0, index = 0, ret;
//不断读取编码数据
//read audio frame
while (av_read_frame(pFormatCtx, packet) >= 0) {
//解码音频类型的Packet
//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;
}
//解码一帧成功
//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);
//拷贝缓冲数据
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);
//释放数组
//release byteArray
(*env)->ReleaseByteArrayElements(env, audio_sample_array, sample_byte_array, 0);
//调用AudioTrack的write方法进行播放
//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);
}

Loading…
Cancel
Save