【发布时间】:2016-10-13 19:52:00
【问题描述】:
问题:
我下载的视频文件无法从任何播放器播放,更不用说我的应用的 VideoView,但它从 URL 到 VideoView 播放效果很好。
做了什么:
我正在下载a video file,如果它不在外部存储中,否则直接从 URL 播放到 VideoView。
VideoView部分代码如下:
final VideoView vvPlayer = (VideoView) findViewById(R.id.vvPlayer);
MediaController mc = new MediaController(MainActivity.this);
mc.setAnchorView(vvPlayer);
vvPlayer.setMediaController(mc);
if (videoFile.exists()) {
// vvPlayer.setVideoURI(Uri.fromFile(videoFile)); <-- Also Tried :(
vvPlayer.setVideoPath(videoFile.getAbsolutePath());
Toast.makeText(this, "Playing from local ...", Toast.LENGTH_SHORT).show();
} else {
vvPlayer.setVideoPath(VIDEO_PATH);
Toast.makeText(this, "Playing online & caching ...", Toast.LENGTH_SHORT).show();
downloadVideoFile();
}
downloadVideoFile() 方法的 AsyncTask 的核心部分,即the doInBackground(),使用以下代码将文件内容作为字符串返回:
@Override
protected String doInBackground(Void... params) {
URLConnection conn;
try {
URL httpFileUrl = new URL(fileUrl);
conn = httpFileUrl.openConnection();
conn.connect();
} catch (IOException e) {
e.printStackTrace();
return null;
}
Log.d(TAG, "Connection opened");
InputStream inputStream;
try {
inputStream = new BufferedInputStream(conn.getInputStream(), 4096);
} catch (IOException e) {
e.printStackTrace();
return null;
}
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(inputStream));
int responseLen = 0;
StringBuilder stringBuilder = new StringBuilder();
String responseStr;
try {
while ((responseStr = bufferedReader.readLine()) != null) {
// Log.i(TAG, "Response read: " + responseStr);
stringBuilder.append(responseStr.trim());
// ...my progress-bar related codes
}
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
responseStr = stringBuilder.toString();
return responseStr;
}
获取文件内容后,我使用以下代码将它们简单地保存在文件中:
try {
if (!APP_DIRECTORY.exists())
APP_DIRECTORY.mkdirs();
if (videoFile.createNewFile())
Log.d(TAG, "Vide-file newly created");
FileOutputStream fos = new FileOutputStream(videoFile);
fos.write(fileContent.getBytes());
fos.flush();
fos.close();
} catch (IOException e) {
Log.d(TAG, "Exception for new creation of videoFile");
e.printStackTrace();
}
最终结果是一个 8.81 MB 的文件,用任何视频播放器都无法将其作为视频文件打开,更不用说我尝试过的 VideoView。
可能是我缺少诸如 codec、encoding 甚至简单的 file-saving 部分之类的东西吗?
【问题讨论】:
-
否,StringBuilder 无法处理二进制视频数据。您不应使用针对文本数据进行调整的 readLine()。从网络获取数据后,立即将数据直接写入 FileOutputStream。不要将其聚合到内存中:视频包含的字节数可能比 RAM 所能容纳的多得多。
标签: android video video-streaming android-videoview