저는 YoutubePlayer에 익숙하지 않지만 오디오 파일을 시작할 때 대기 시간을 줄이면 AudioTrack을 사용하는 것이 더 낫습니다 (또는 openSL에 익숙한 사용자는 video을 확인하십시오).
오디오를 괜찮은 결과로 동기화하는 데 사용한 간단한 해결 방법은 AudioTrack을 설정하고 오디오 파일의 PCM 데이터를 바이트 배열로 읽는 것입니다. 그런 다음 AudioTrack 플레이로 스레드를 만들고 내부에 명령을 작성하십시오. 오디오 파일 재생을 시작할 준비가되면 스레드에서 start를 호출하십시오. 샘플링 속도, 채널 및 형식은 스트리밍하는 오디오 파일에 따라 다릅니다.
int minBufferSize = AudioTrack.getMinBufferSize(441000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
at = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
filepath = Environment.getExternalStorageDirectory().getPath() + File.separator + "audiofile.wav";
fp = new File(Environment.getExternalStorageDirectory().getPath() + File.separator + "audiofile.wav");
count = 0;
data = new byte[(int) fp.length()];
try {
fis = new FileInputStream(filepath);
dis = new DataInputStream(fis);
while((count = dis.read(data, 0, (int) fp.length())) > -1){}
data = null;
dis.close();
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
atThread = new Thread(new Runnable() {
public void run() {
at.play();
at.write(data, 0, (int) fp.length());
data = null; at.stop(); at.flush(); at.release();
}
});
희망이 있습니다.
편집 : 도움을 @WilliamMorrison에
BIG 감사합니다! @ inazaruk의 대답 here을 수정 한 후 전체 파일을 메모리에 쓰지 않고도 별도의 웨이브 파일을 재생할 수있었습니다. 휴!
AudioTrack song_1, song_2;
boolean stop = false;
Button start_btn, stop_btn;
DataInputStream dis_1, dis_2;
File file_1 = new File(Environment.getExternalStorageDirectory().toString() + "/song_1.wav");
File file_2 = new File(Environment.getExternalStorageDirectory().toString() + "/song_2.wav");
FileInputStream fis_1, fis_2;
int minBufferSize;
Thread thread_1, thread_2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start_btn = (Button)findViewById(R.id.start);
start_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
start();
}
});
stop_btn = (Button)findViewById(R.id.stop);
stop_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
stop();
}
});
}
Runnable read_song1 = new Runnable() {
public void run() {
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
byte [] audio_data = new byte[minBufferSize];
try {
while(!stop) {
dis_1.read(audio_data, 0, minBufferSize);
song_1.write(audio_data, 0, audio_data.length);
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
};
Runnable read_song2 = new Runnable()
{
public void run() {
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
byte [] audio_data = new byte[minBufferSize];
try {
while(!stop) {
dis_2.read(audio_data, 0, minBufferSize);
song_2.write(audio_data, 0, audio_data.length);
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
};
void start() {
try {
fis_1 = new FileInputStream(file_1); fis_2 = new FileInputStream(file_2);
dis_1 = new DataInputStream(fis_1); dis_2 = new DataInputStream(fis_2);
stop = false;
minBufferSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
song_1 = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
song_2 = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
song_1.play(); song_2.play();
thread_1 = new Thread(read_song1); thread_2 = new Thread(read_song2);
thread_1.start(); thread_2.start();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
}
void stop() {
stop = true;
song_1.stop(); song_2.stop();
song_1.flush(); song_2.flush();
song_1.release(); song_2.release();
try {
dis_1.close(); dis_2.close();
fis_1.close(); fis_2.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
좋은 예입니다. 독자는이 코드가 PCM 오디오 파일 전체를 메모리로 읽는 것을 알고 있습니다. 이는 짧은 파일에는 적합하지만 긴 파일에는 적합하지 않음을 의미합니다. –
아, 좋은 지적이야! 윌리엄에게 감사드립니다. – jch000
@WilliamMorrison는 한 번에 메모리에 PCM 오디오 파일의 일부를 작성하는 방법에 대한 조언을해야합니까? 아마 뭔가 명백한 것을 놓치고 있지만 적절한 방법을 찾을 수없는 것 같습니다. 어떤 방향이라도 대단히 감사 할 것입니다! =] – jch000