音视频开发之Android端native层播放音频三种方式
下面三种方式前两种区别不大,缺点是必须要等到系统加载差不多了才可以使用。Android系统启动时间很长,想要早点播放的话可以选择第三种,tinyalsa播放。好像还有第四种,使用openGL ES,这个没怎么研究过。二. MediaPlayer。一. AudioTrack。三. tinyalsa。
·
下面三种方式前两种区别不大,缺点是必须要等到系统加载差不多了才可以使用。Android系统启动时间很长,想要早点播放的话可以选择第三种,tinyalsa播放。
一. AudioTrack
auto lpTrack = new AudioTrack();
status_t status = lpTrack->set(
AUDIO_STREAM_MUSIC,
24000,
AUDIO_FORMAT_PCM_16_BIT,
AUDIO_CHANNEL_OUT_MONO,
0,
AUDIO_OUTPUT_FLAG_FAST,
audioCallback, this, //callback callback
0,
0,
true,
AUDIO_SESSION_ALLOCATE, //sessionId
AudioTrack::TRANSFER_SYNC);
if (status != NO_ERROR) {
ALOGE("Error %d initializing AudioTrack", status);
return;
}
lpTrack->stop();
lpTrack->start();
while(offset < pcm_out_length){
written = lpTrack->write(pcm_out + offset, pcm_out_length - offset);
offset += written;
ALOGE("%s written %d, offset %d, pcm_out %d", __FUNCTION__, written, offset, pcm_out_length);
if(written < 0) break;
}
final String TEST_NAME = "testPlaybackHeadPositionAfterFlush";
final int TEST_SR = 22050;
final int TEST_CONF = AudioFormat.CHANNEL_OUT_STEREO;
final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
final int TEST_MODE = AudioTrack.MODE_STREAM;
final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
//-------- initialization --------------
int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT, minBuffSize, TEST_MODE);
byte data[] = new byte[minBuffSize/2];
//-------- test --------------
track.write(data, 0, data.length);
track.write(data, 0, data.length);
track.play();
Thread.sleep(100);
track.stop();
track.flush();
//-------- tear down --------------
track.release();
二. MediaPlayer

三. tinyalsa
struct pcm_config config;
struct pcm *pcm;
char *buffer;
unsigned int size, read_sz;
int num_read;
memset(&config, 0, sizeof(config));
config.channels = channels;
config.rate = rate;
config.period_size = period_size;
config.period_count = period_count;
config.format = PCM_FORMAT_S16_LE;
config.start_threshold = 0;
config.stop_threshold = 0;
config.silence_threshold = 0;
pcm = pcm_open(card, device, PCM_OUT, &config);
if (!pcm || !pcm_is_ready(pcm)) {
fprintf(stderr, "Unable to open PCM device %u (%s)\n", device, pcm_get_error(pcm));
return;
}
size = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm));
buffer = malloc(size);
do {
read_sz = size < data_sz ? size : data_sz;
num_read = fread(buffer, 1, read_sz, file);
if (num_read > 0) {
if (pcm_write(pcm, buffer, num_read)) {
fprintf(stderr, "Error playing sample\n");
break;
}
data_sz -= num_read;
} while (!close && num_read > 0 && data_sz > 0);
free(buffer);
pcm_close(pcm);
好像还有第四种,使用openGL ES,这个没怎么研究过。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)