Как протестировать аутентифицированный контент с помощью 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-адресе?