所以我的资产文件夹中有一个小音频文件,我想打开一个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
修好了。事实证明,在将缓冲区写入“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();
这是对我有用的代码
//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();
}
}
该文件应该位于资产文件夹中
如果您想播放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));