我正在将Web应用程序中的MP4文件下载到移动设备上的文件中。由于文件往往很大,我想在得到一些数据后立即开始播放它们,而不是等到整个文件下载完毕,所以我想出了以下方案:
更确切地说,代码执行以下操作:
创建一个名为out的FileOutputstream,写入“/ storage / sdcard / tmpAttachment” 从服务器获取最多1 MB并将其写入/ storage / sdcard / tmpAttachment 启动视频播放器,让它从/ storage / sdcard / tmpAttachment开始播放 而(更多数据) 获取下一个1 MB块并写出 ENDWHILE
实际代码如下:
File file = new File(Environment.getExternalStorageDirectory() + "/tmpAttachment");
if (file.exists() && !file.delete()) { //Delete the old file if it exists
postRes = mContext.getString(R.string.message_view_dynamic_content_delete_error);
mHandler.post(mUpdateResults);
return;
}
FileOutputStream out = new FileOutputStream(file);
reply = Utility.doFetchSegment(mAccount, mMessage.getFrom()[0].getAddress() + Utility.BLANK + contentPointers[i] + Utility.BLANK + "0", "https://" + contentServerName + ":" + contentServerPort, mAccount.getEmail(), contentServerPassword, true, out, null);
if (reply[0].equals("13")) {
Uri attachmentUri = Uri.fromFile(file);
attachmentViewIntent = new Intent(mContext, ECSVideoViewer.class);
try {
ECSVideoViewer.actionECSVideoViewer(mContext, attachmentUri);
} catch (Exception e) {
postRes = mContext.getString(R.string.message_view_dynamic_content_fetch_error) + e;
mHandler.post(mUpdateResults);
e.printStackTrace();
}
while (!fPtr.equals(contentLen)) {
reply = Utility.doFetchSegment(mAccount, mMessage.getFrom()[0].getAddress() + Utility.BLANK + contentPointers[i] + Utility.BLANK + fPtr, "https://" + contentServerName + ":" + contentServerPort, mAccount.getEmail(), contentServerPassword, true, out, null);
if (reply[0].equals("13")) {
fPtr = reply[1].substring(reply[1].indexOf("pointer=") + "pointer=".length(), reply[1].indexOf(", t"));
} else {
postRes = reply[1];
mHandler.post(mUpdateResults);
out.close();
return;
}
}
ECSVideoViewer.java的代码如下:
public class ECSVideoViewer extends Activity {
private static final String EXTRA_PATH = "path";
/**
* TODO: Set the path variable to a streaming video URL or a local media
* file path.
*/
private static VideoView mVideoView;
public static void actionECSVideoViewer(Context context, Uri uri) {
Intent i = new Intent(context, ECSVideoViewer.class);
i.putExtra(EXTRA_PATH, uri.getEncodedPath());
context.startActivity(i);
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.videoview);
mVideoView = (VideoView) findViewById(R.id.surface_view);
String path = getIntent().getStringExtra(EXTRA_PATH);
mVideoView.setVideoURI(Uri.parse(path));
mVideoView.setMediaController(new MediaController(this));
mVideoView.setOnErrorListener(new OnErrorListener() {
public boolean onError (MediaPlayer mp, int what, int extra) {
mVideoView.getCurrentPosition();
mVideoView.getBufferPercentage();
mVideoView.getDuration();
return true;
}
});
mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion (MediaPlayer mp) {
mVideoView.pause();
}
});
mVideoView.requestFocus();
mVideoView.start();
}
public static void resume() {
mVideoView.resume();
}
public static void play() {
mVideoView.start();
}
public static int getCurrentPosition() {
return mVideoView.getCurrentPosition();
}
public static int getBufferPercentage() {
return mVideoView.getBufferPercentage();
}
public static int getDuration() {
return mVideoView.getDuration();
}
public static boolean isPlaying() {
return mVideoView.isPlaying();
}
}
视频开始播放正常,加载第一个块并且下一个块加载后,但由于某种原因,播放器在尝试读取第二个1 MB下载数据块时停止并抛出错误,返回MEDIA_ERROR_UNKNOWN和MEDIA_ERROR_IO。谁能看到我做错了什么?