Как протестировать аутентифицированный контент с помощью MediaPlayer на Android
Я видел довольно много сообщений, задающих этот вопрос на SO, но, похоже, не существует окончательного ответа (или, по крайней мере, ответа, который мне нравится!)
У меня есть контент, защищенный за базовым auth (имя пользователя/пароль). Я могу загрузить его с помощью различных загрузок HTTP-загрузки, но для жизни я не могу разобраться, как сообщить медиа-плееру о его потоке (и обеспечить аутентификацию). Я видел одно сообщение, которое предположило, что это невозможно, так как MediaPlayer - это весь собственный код и не похоже на Authenticator.
Есть много примеров того, как сначала загружать в кешированную копию, а затем воспроизводить ее, но.... Такого рода отстой (и файлы, возможно, 100 МБ). Я видел по крайней мере одно предложение загрузить его в малейших кусках, а затем начать и остановить воспроизведение (перенаправление на новый файл), но это отстойно, так как там (я полагаю) будет заикаться (я не пробовал, хотя )
Лучшая идея, которую я имею на этом этапе, - начать загрузку в кэш файл, а затем, когда она "достаточно полно", начнет воспроизведение, пока я продолжаю заполнять файл... Я надеюсь, что это сработает (но опять же, не пробовал).
Я пропустил что-то очевидное? Это так больно, что все различные части почти работают, и я сам убедился в том, что должен существовать способ изнасиловать защищенный контент (или использовать уже установленный и квалифицированный InputStream), но он не выглядит радостью.
BTW Я парень Mac/iPhone и новичок на Android, поэтому я все еще боюсь немного обучения Java... Извините, если я упустил что-то очевидное.
Ответы
Ответ 1
Если вы управляете сервером, одним из вариантов может быть его изменение, чтобы можно было создать временный, случайный URL-адрес для контента при аутентификации, а затем передать его. Будут ли потоковые функции принимать URL-адрес, содержащий параметры script?
Чтобы сделать все по-настоящему на телефоне, другой вариант заключался бы в том, чтобы написать тривиальный HTTP-прокси, такой как сервер, в java или native-коде и запустить его в фоновом потоке. Вместо того, чтобы указывать медиаплеер на сервере, вы должны указать его на свой собственный прокси-сервер. Прокси-сервер будет передавать запросы удаленному серверу при обработке аутентификации.
Ответ 2
Один из подходов - загрузить данные самостоятельно, декодировать их (от??? до PCM) и использовать AudioTrack для воспроизведения PCM. Уловка в декодировании. Какой формат представляет поток, закодированный в?
Необработанные декодеры для общих протоколов доступны на Android, но в библиотеках C. Таким образом, вам, возможно, придется добавить слой JNI для выполнения вашего декодирования, опять же, в зависимости от того, в какой кодировке находится ваш поток.
Ответ 3
У меня была такая же проблема, и я решил ее, поместив учетные данные в URL-адрес. Он официально не поддерживается для HTTP, но большинство веб-клиентов поддерживают его.
Следующий код основан на этом учебнике: http://www.coderzheaven.com/2012/08/14/stream-audio-android/
try {
// You can use HTTPS or HTTP as protocol.
String myURL = "https://example.com/song.mp3";
mp.reset();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setOnPreparedListener(this);
mp.setOnErrorListener(this);
// These are the two lines, doing the magic ;) It transforms it to a url like this: https://user:[email protected]/song.mp3
UsernamePasswordCredentials credentials = connHelper.getCredetials();
myURL = myURL.replace("://", "://" + URLEncoder.encode(credentials.getUserName(), "UTF-8") + ":" + URLEncoder.encode(credentials.getPassword(), "UTF-8") + "@");
mp.setDataSource(myURL);
mp.prepareAsync();
mp.setOnCompletionListener(this);
} catch (Exception e) {
Log.e("StreamAudioDemo", e.getMessage());
}
ПРИМЕЧАНИЕ.. Используя URLEncoder здесь, мы хотим избавиться от таких проблем, как: Если имя пользователя или пароль содержит двоеточие или @.
ПРИМЕЧАНИЕ2: Он может работать или не работать для вас, в зависимости от вашего сервера. Если вы столкнулись с этой проблемой, я предлагаю вам взглянуть на этот вопрос: Почему браузеры не отправляют заголовок аутентификации, когда учетные данные указаны в URL-адресе?