質問

Mediaplayerオブジェクトのデータソースとして任意のinputstreamを使用したいと思います。

この理由は、私が使用している入力ストリームが実際にリモートサーバー上のメディアリソースへの承認されたHTTPS接続であるためです。その場合、URLを渡すには、認証が必要であるため、明らかに機能しません。ただし、認証を個別に行い、リソースに入力ストリームを取得することができます。問題が発生したらどうすればよいですか?

名前付きパイプを使用して、そのファイリングエクスプトターをMediaplayerのSetDataresourceメソッドに渡すオプションについて考えました。 Androidで名前のパイプを作成する方法はありますか(NDKを使用せずに)?

他の提案は大歓迎です。

役に立ちましたか?

解決 2

別の解決策は、LocalHostでプロキシHTTPサーバーを起動することです。メディアプレーヤーは、SetDataSource(コンテキストコンテキスト、URI URI)でこのサーバーに接続します。このソリューションは以前よりもうまく機能し、再生がグリッチになることはありません。

他のヒント

解決策を見つけたと思います。興味のある他の人が自分でこれを試して、デバイスモデルとSDKバージョンで結果を報告するなら、私はそれを感謝します。

私はこれに直接対応する同様の投稿を見てきましたが、とにかく新しいバージョンのSDKで動作するように見えるので、とにかく投稿すると思いました - これまでのところ、Android 2.3.6を実行しているNexus Oneで動作します。

ソリューションは、入力ストリームをローカルファイルにバッファリングすることに依存しています(外部ストレージにこのファイルがありますが、おそらくIntenalストレージにも配置することができます)。

以下は、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イベントのハンドラーを設定します。最も重要なのは、再生が完了したときに呼び出されるoncomplediotionListenerです。バッファーアンダーランの場合(たとえば、一時的な遅いネットワーク接続により)、プレーヤーはローカルファイルの終わりに到達し、再生コンプレット状態にトランジットします。 _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
                }
            }
        }
    );
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top