如何在 MediaPlayer 上播放 Android InputStream?

发布于 2024-11-02 17:58:40 字数 2531 浏览 1 评论 0原文

因此,我的资产文件夹中有一个小音频文件,我想打开一个 InputStream 来写入缓冲区,然后写入一个临时文件,然后打开 MediaPlayer 来播放该临时文件。问题是,当媒体播放器点击 mp.Prepare() 时,它不会播放并且永远不会到达 toast。以前有人这样做过吗?

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    InputStream str;

    try {

        str = this.getAssets().open("onestop.mid");
        Toast.makeText(this, "Successful Input Stream Opened.", Toast.LENGTH_SHORT).show();
        takeInputStream(str);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}//end on create

public void takeInputStream(InputStream stream) throws IOException
{
    //fileBeingBuffered = (FileInputStream) stream;
    //Toast.makeText(this, "sucessful stream conversion.", Toast.LENGTH_SHORT).show();
    try
    {
        convertedFile = File.createTempFile("convertedFile", ".dat", getDir("filez", 0));
        Toast.makeText(this, "Successful file and folder creation.", Toast.LENGTH_SHORT).show();

        out = new FileOutputStream(convertedFile);
        Toast.makeText(this, "Success out set as output stream.", Toast.LENGTH_SHORT).show();

        //RIGHT AROUND HERE -----------

        byte buffer[] = new byte[16384];
        int length = 0;
        while ( (length = stream.read(buffer)) != -1 ) 
        {
          out.write(buffer,0, length);
        }

        //stream.read(buffer);
        Toast.makeText(this, "Success buffer is filled.", Toast.LENGTH_SHORT).show();
        out.close();

        playFile();
    }catch(Exception e)
    {
        Log.e(TAG, e.toString());
        e.printStackTrace();
    }//end catch
}//end grabBuffer

public void playFile()
{
    try {
        String path = convertedFile.getAbsolutePath();
        mp = new MediaPlayer();
        mp.setDataSource(path);
        Toast.makeText(this, "Success, Path has been set", Toast.LENGTH_SHORT).show();

        mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mp.prepare();
        Toast.makeText(this, "Media Player prepared", Toast.LENGTH_SHORT).show();

        mp.start();
        Toast.makeText(this, "Media Player playing", Toast.LENGTH_SHORT).show();
    } catch (IllegalArgumentException e) {
        Log.e(TAG, e.toString());
        e.printStackTrace();
    } catch (IllegalStateException e) {
        Log.e(TAG, e.toString());
        e.printStackTrace();
    } catch (IOException e) {
        Log.e(TAG, e.toString());
        e.printStackTrace();
    }

}//end playFile

So I have a small audio file in my assets folder and I wanted to open a InputStream to write to a buffer, then write to a temporary File, then I open up the MediaPlayer to play that temporary File. Problem is, when the media player hits mp.Prepare(), it doesn't play and never reaches the toast. Has anyone ever done this before?

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    InputStream str;

    try {

        str = this.getAssets().open("onestop.mid");
        Toast.makeText(this, "Successful Input Stream Opened.", Toast.LENGTH_SHORT).show();
        takeInputStream(str);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}//end on create

public void takeInputStream(InputStream stream) throws IOException
{
    //fileBeingBuffered = (FileInputStream) stream;
    //Toast.makeText(this, "sucessful stream conversion.", Toast.LENGTH_SHORT).show();
    try
    {
        convertedFile = File.createTempFile("convertedFile", ".dat", getDir("filez", 0));
        Toast.makeText(this, "Successful file and folder creation.", Toast.LENGTH_SHORT).show();

        out = new FileOutputStream(convertedFile);
        Toast.makeText(this, "Success out set as output stream.", Toast.LENGTH_SHORT).show();

        //RIGHT AROUND HERE -----------

        byte buffer[] = new byte[16384];
        int length = 0;
        while ( (length = stream.read(buffer)) != -1 ) 
        {
          out.write(buffer,0, length);
        }

        //stream.read(buffer);
        Toast.makeText(this, "Success buffer is filled.", Toast.LENGTH_SHORT).show();
        out.close();

        playFile();
    }catch(Exception e)
    {
        Log.e(TAG, e.toString());
        e.printStackTrace();
    }//end catch
}//end grabBuffer

public void playFile()
{
    try {
        String path = convertedFile.getAbsolutePath();
        mp = new MediaPlayer();
        mp.setDataSource(path);
        Toast.makeText(this, "Success, Path has been set", Toast.LENGTH_SHORT).show();

        mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mp.prepare();
        Toast.makeText(this, "Media Player prepared", Toast.LENGTH_SHORT).show();

        mp.start();
        Toast.makeText(this, "Media Player playing", Toast.LENGTH_SHORT).show();
    } catch (IllegalArgumentException e) {
        Log.e(TAG, e.toString());
        e.printStackTrace();
    } catch (IllegalStateException e) {
        Log.e(TAG, e.toString());
        e.printStackTrace();
    } catch (IOException e) {
        Log.e(TAG, e.toString());
        e.printStackTrace();
    }

}//end playFile

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

羁〃客ぐ 2024-11-09 17:58:40

修好了。事实证明,在将缓冲区写入“File”创建的临时文件中后,您可以使用 FileInputStream 打开该文件,然后继续播放它,如下所示。感谢你们所有的帮助。

mp = new MediaPlayer();

FileInputStream fis = new FileInputStream(convertedFile);
mp.setDataSource(fis.getFD());

Toast.makeText(this, "Success, Path has been set", Toast.LENGTH_SHORT).show();

mp.prepare();
mp.start();

Fixed it. Turns out that after writing the buffer in the temporary file created by "File," you can then open that file using a FileInputStream, then proceed to play it shown below. Thanks for all your help guys.

mp = new MediaPlayer();

FileInputStream fis = new FileInputStream(convertedFile);
mp.setDataSource(fis.getFD());

Toast.makeText(this, "Success, Path has been set", Toast.LENGTH_SHORT).show();

mp.prepare();
mp.start();
恋竹姑娘 2024-11-09 17:58:40

这是对我有用的代码,

//preserved to stop previous actions 
MediaPlayer lastmp;

public void playSound(String file) {
    try {
        if (lastmp!=null) lastmp.stop();
        MediaPlayer mp = new MediaPlayer();
        lastmp = mp;
        AssetFileDescriptor descriptor;

        AssetManager assetManager = act.getAssets();

        descriptor =  assetManager.openFd(fileName);
        mp.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
        descriptor.close();
        mp.prepare();
        mp.start();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

文件应该位于资产文件夹中

This is the code that worked for me

//preserved to stop previous actions 
MediaPlayer lastmp;

public void playSound(String file) {
    try {
        if (lastmp!=null) lastmp.stop();
        MediaPlayer mp = new MediaPlayer();
        lastmp = mp;
        AssetFileDescriptor descriptor;

        AssetManager assetManager = act.getAssets();

        descriptor =  assetManager.openFd(fileName);
        mp.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
        descriptor.close();
        mp.prepare();
        mp.start();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

the file shoud be on the assets folder

牛↙奶布丁 2024-11-09 17:58:40

如果您想播放InputStream而不将其保存在任何地方(出于安全原因)。

这对您有用:

import android.media.MediaDataSource;
import java.io.IOException;
import java.io.InputStream;

public class InputStreamMediaDataSource extends MediaDataSource {
    private InputStream inputStream;
    private long size;

    public InputStreamMediaDataSource(InputStream inputStream, long size) {
        this.inputStream = inputStream;
        this.size = size;
    }

    @Override
    public int readAt(long position, byte[] buffer, int offset, int size) throws IOException {
        if (position >= this.size) {
            return -1;  // End of data
        }
        if (position + size > this.size) {
            size = (int) (this.size - position);
        }

        inputStream.reset();
        inputStream.skip(position);

        return inputStream.read(buffer, offset, size);
    }

    @Override
    public long getSize() throws IOException {
        return size;
    }

    @Override
    public void close() throws IOException {
        inputStream.close();
    }
}

然后我将其用作:

mMediaPlayer.setDataSource(new InputStreamMediaDataSource(mInputStream, mSize));

警告: Min-SDK =23

If you want to play InputStream without saving it anywhere (for security reasons).

This will work for you:

import android.media.MediaDataSource;
import java.io.IOException;
import java.io.InputStream;

public class InputStreamMediaDataSource extends MediaDataSource {
    private InputStream inputStream;
    private long size;

    public InputStreamMediaDataSource(InputStream inputStream, long size) {
        this.inputStream = inputStream;
        this.size = size;
    }

    @Override
    public int readAt(long position, byte[] buffer, int offset, int size) throws IOException {
        if (position >= this.size) {
            return -1;  // End of data
        }
        if (position + size > this.size) {
            size = (int) (this.size - position);
        }

        inputStream.reset();
        inputStream.skip(position);

        return inputStream.read(buffer, offset, size);
    }

    @Override
    public long getSize() throws IOException {
        return size;
    }

    @Override
    public void close() throws IOException {
        inputStream.close();
    }
}

Then i use it as:

mMediaPlayer.setDataSource(new InputStreamMediaDataSource(mInputStream, mSize));

Warning: Min-SDK=23

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文