我正在开发以 mp4 格式录制视频并将其上传到服务器的 android 应用程序,然后其他用户可以查看该视频。
我的问题是 mp4 不支持我在我的应用程序中需要的流式传输,相反它需要下载所有视频才能开始播放。
我搜索了这个问题,我发现支持流式传输的 mp4 具有 faststart 属性,它将 moov 原子放在视频文件的开头。
我的问题是如果可以的话如何在android中实现?如果不能,我可以在服务器上执行吗?如何执行?
我录制视频的代码是:
if (requestCode == REQUEST_VIDEO_CAPTURE ) {
try
{
Log.e("videopath","videopath");
AssetFileDescriptor videoAsset = getContentResolver().openAssetFileDescriptor(data.getData(), "r");
FileInputStream fis = videoAsset.createInputStream();
File root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
if (!root.exists()) {
root.mkdirs();
}
File file;
file=new File(root,"android_"+System.currentTimeMillis()+".mp4" );
videoUri = Uri.fromFile(file);
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) > 0) {
fos.write(buf, 0, len);
}
fis.close();
fos.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return;
}
最佳答案
如果您可以选择适合您的场景,我建议您对服务器上的视频进行修改,因为您通常在服务器上拥有更多“马力”并且对您的用户的影响更小。
我认为您可能还会发现它更容易 - 虽然您可以将 ffmpeg 集成到您的 Android 应用程序中,但这并非易事,您必须小心更新应用程序的新版本。
在服务器端执行此操作的一种相对简单的方法是运行一个作业或任务,该作业或任务使用命令行程序调用 ffmpeg 来进行转换——它可能不如直接使用 ffmpeg C 库有效,但它有当 ffmpeg 本身发生变化时易于更新的优势,以及您通常会发现更多关于从命令行使用 ffmpeg 的讨论和帮助的优势。
选项等会随着时间的推移而改变,所以这可能会过时,但以下格式(来自这个 stackOverflow 答案:https://stackoverflow.com/a/14172629/334402)以前对我有用:
ffmpeg -i <input> -c:v libx264 -profile:v baseline -c:a libfaac -ar 44100 -ac 2 -b:a 128k -movflags faststart output.mp4
如果您确实想在 Android 应用程序上执行此操作,则可以使用相同的格式(如果您使用 Android 包装器库之一),或者您可以编写自己的 fffmpeg 包装器库。也可以直接在 Android 中使用 ffmpeg C 库,尽管我个人并没有对此表示反对。
如果您想使用 Android ffmpeg 包装器,以下是一个很好的起点:
在上面的第二个链接中,请务必特别注意有关两次调用 ffmpeg 的注释。这可能很棘手,因为它最初似乎有效,但会在多次运行时崩溃。
关于android - 转换 mp4 视频以支持在 android 中流式传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30714932/