Android Mediaplayer: проблема setDataSource для загруженного медиафайла
У меня есть приложение, которое будет записывать и воспроизводить аудиофайлы. Некоторые аудиофайлы загружаются с использованием простых стандартных HTTP-загрузок с использованием httpclient. Он работал как прелесть в течение длительного времени. Теперь я не могу воспроизвести файлы, которые я загружаю. Он не работает с этим стеком. Я храню файлы на SDCard, и я испытываю эту проблему как на телефонной трубке, так и на USB-подключенном устройстве.
Я проверил, что загруженный файл остывает на сервере, и я могу воспроизвести его без каких-либо проблем.
Это фрагменты кода, которые я использую (я знаю, что recordFile является допустимым путем для файла).
// inside the activity class
private void playRecording() throws IOException{
File recordingFile = new File(recordingFileName);
FileInputStream recordingInputStream = new FileInputStream(recordingFile);
audioMediaPlayer.playAudio(recordingInputStream);
}
Вот код медиаплеера:
// inside my media player class which handles the recordings
public void playAudio(FileInputStream audioInputStream) throws IOException {
mediaPlayer.reset();
mediaPlayer.setDataSource(audioInputStream.getFD());
mediaPlayer.prepare();
mediaPlayer.start();
}
Вот исключение:
E/MediaPlayerService( 555): offset error
E/MediaPlayer( 786): Unable to to create media player
W/System.err( 786): java.io.IOException: setDataSourceFD failed.: status=0x80000000
W/System.err( 786): at android.media.MediaPlayer.setDataSource(Native Method)
W/System.err( 786): at android.media.MediaPlayer.setDataSource(MediaPlayer.java:632)
W/System.err( 786): at net.xxx.xxx.AudioMediaPlayer.playAudio(AudioMediaPlayer.java:69)
W/System.err( 786): at net.xxx.xxx.Downloads.playRecording(Downloads.java:299)
W/System.err( 786): at net.xxx.xxx.Downloads.access$0(Downloads.java:294)
W/System.err( 786): at net.xxx.xxx.Downloads$1.onClick(Downloads.java:135)
Я попытался найти ответ на ошибку смещения, но не совсем понимаю, что это может быть.
PS Загрузите файл с помощью этого кода:
public FileOutputStream executeHttpGet(FileOutputStream fileOutputStream) throws ClientProtocolException, IOException{
try {
// Execute HTTP Post Request
httpResponse = httpClient.execute(httpPost, localContext);
int status = httpResponse.getStatusLine().getStatusCode();
// we assume that the response body contains the error message
if (status != HttpStatus.SC_OK) {
ByteArrayOutputStream ostream = new ByteArrayOutputStream();
httpResponse.getEntity().writeTo(ostream);
fileOutputStream = null;
} else {
InputStream content = httpResponse.getEntity().getContent();
byte[] buffer = new byte[1024];
int len = 0;
while ( (len = content.read(buffer)) > 0 ) {
fileOutputStream.write(buffer,0, len);
}
fileOutputStream.close();
content.close(); // this will also close the connection
}
} catch (ClientProtocolException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
fileOutputStream = null;
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
fileOutputStream = null;
}
return fileOutputStream;
}
Ответы
Ответ 1
Я решил это самостоятельно. Как я сказал выше, решение было следующим:
Когда я реорганизовал часть кода, я сделал опечатку на хеш-код, который я использую, чтобы разрешить загрузку, а не. К сожалению, у меня не было правильного улова, когда я загрузил файл, чтобы файл был пустым. В основном я отправляю заголовок плохого запроса, если вы пытаетесь получить файл без соответствующего кода активации.
Преступник был здесь:
if (status != HttpStatus.SC_OK) {
ByteArrayOutputStream ostream = new ByteArrayOutputStream();
httpResponse.getEntity().writeTo(ostream);
fileOutputStream = null;
} else {
InputStream content = httpResponse.getEntity().getContent();
byte[] buffer = new byte[1024];
int len = 0;
while ( (len = content.read(buffer)) > 0 ) {
fileOutputStream.write(buffer,0, len);
}
fileOutputStream.close();
content.close(); // this will also close the connection
}
В случаях, когда код состояния возвращался как плохой (т.е. заголовок плохого запроса для заблокированных обращений). То, что я пропустил, состояло в том, чтобы зафиксировать случай с нулевым указателем, и это привело к тому, что запись SQLite была обновлена, заявив приложению, что загрузка прошла успешно, но это не так.
Извлеченный урок: всегда ставьте нулевые проверки для этих случаев даже для прототипов.: -)
Ответ 2
Во-первых, убедитесь, что ваше устройство не смонтировано. Либо Android, либо хост-компьютер могут получить доступ к SD-карте, но не оба одновременно.
Во-вторых, непонятно, почему вы используете FileInputStream
и getFD()
. Просто передайте путь к файлу на SD-карте в MediaPlayer
(например, new File(Environment.getExternalStorageDirectory(), "yourfile.mp3")
) и дайте игроку открыть файл.