나는 해결책을 찾았다 고 생각합니다. 관심있는 다른 사람들이 직접 시도해보고 장치 모델 및 SDK 버전으로 결과를보고 해 주시면 감사하겠습니다.
나는 비슷한 게시물을 보았지만, 어쨌든 최신이며 SDK의 최신 버전에서 작동하는 것처럼 보인다. 지금까지 Android 2.3.6을 실행하는 Nexus One에서 작동한다.
이 솔루션은 입력 스트림을 로컬 파일로 버퍼링하는 데 의존합니다 (외부 저장소에이 파일이 있지만 내부 저장소에도 파일을 배치 할 수 있음) MediaPlayer 인스턴스에 해당 파일의 설명자를 제공 할 수 있습니다 .
AudioPlayback 않는 일부 AsyncTask를하는 doInBackground 방법에서 다음을 실행 :
@Override
protected
Void doInBackground(LibraryItem... params)
{
...
MediaPlayer player = new MediaPlayer();
setListeners(player);
try {
_remoteStream = getMyInputStreamSomehow();
File tempFile = File.createTempFile(...);
tempFile.deleteOnExit();
_localInStream = new FileInputStream(tempFile);
_localOutStream = new FileOutputStream(tempFile);
int buffered = bufferMedia(
_remoteStream, _localOutStream, BUFFER_TARGET_SIZE // = 128KB for instance
);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource(_localInStream.getFD());
player.prepareAsync();
int streamed = 0;
while (buffered >= 0) {
buffered = bufferMedia(
_remoteStream, _localOutStream, BUFFER_TARGET_SIZE
);
}
}
catch (Exception exception) {
// Handle errors as you see fit
}
return null;
}
bufferMedia 방법 버퍼 nBytes 바이트 또는 입력의 끝에 도달 할 때까지 :
private
int bufferMedia(InputStream inStream, OutputStream outStream, int nBytes)
throws IOException
{
final int BUFFER_SIZE = 8 * (1 << 10);
byte[] buffer = new byte[BUFFER_SIZE]; // TODO: Do static allocation instead
int buffered = 0, read = -1;
while (buffered < nBytes) {
read = inStream.read(buffer);
if (read == -1) {
break;
}
outStream.write(buffer, 0, read);
outStream.flush();
buffered += read;
}
if (read == -1 && buffered == 0) {
return -1;
}
return buffered;
}
setListeners 방법 다양한 MediaPlayer 이벤트에 대한 핸들러를 설정합니다. 가장 중요한 것은 재생 완료시 이 호출되는 OnCompletionListener입니다. 버퍼 언더런의 경우 (즉, 느린 네트워크 연결로 인해) 플레이어 은 로컬 파일의 끝에 도달하고 PlaybackCompleted 상태로 이동합니다. 필자는 _localInStream의 위치 인 을 입력 스트림의 크기와 비교하여 이러한 상황을 확인합니다. 위치가 작은 경우, 재생이 이제 정말 을 완료하고 난 MediaPlayer를을 재설정 :
private
void setListeners(MediaPlayer player)
{
// Set some other listeners as well
player.setOnSeekCompleteListener(
new MediaPlayer.OnSeekCompleteListener()
{
@Override
public
void onSeekComplete(MediaPlayer mp)
{
mp.start();
}
}
);
player.setOnCompletionListener(
new MediaPlayer.OnCompletionListener()
{
@Override
public
void onCompletion(MediaPlayer mp)
{
try {
long bytePosition = _localInStream.getChannel().position();
int timePosition = mp.getCurrentPosition();
int duration = mp.getDuration();
if (bytePosition < _track.size) {
mp.reset();
mp.setDataSource(_localInStream.getFD());
mp.prepare();
mp.seekTo(timePosition);
} else {
mp.release();
}
} catch (IOException exception) {
// Handle errors as you see fit
}
}
}
);
}
이것이 차이가 있는지 확인할 수는 없지만 운이 좋다면 우리는 Uri가''https : // username : password @ server.com/stream.data'' 인증을 지원할 수도 있습니다. 인증이 기본 인증과 다른 경우 이는 매우 명백합니다. – harism
아니요, 인증은 암호를 기반으로하지 않습니다. – smichak