背景
我们希望让用户从任何应用程序中选择视频,然后将视频剪辑为最长为5秒。
问题
对于获取要选择的Uri,我们已经找到了有效的解决方案(该解决方案在这里可用)。
至于剪辑本身,我们无法找到任何具有宽容许可证的好库,除了一个名为"k4l-video-trimmer"的库。例如,库"FFmpeg"被认为不允许使用GPLv3,这要求使用它的应用程序也是开源的。此外,据我所知,它需要相当多的空间(约9MB)。
不幸的是,这个库(k4l-video-trimmer)非常古老,多年没有更新,所以我不得不分叉它(这里)来处理它。它使用一个名为"mp4parser"的开源库进行剪辑。
问题在于,这个库似乎只能处理文件,而不能处理Uri
或InputStream
,所以即使选择无法到达的项目(如普通文件)或甚至具有无法处理的路径的路径时,示例也可能会崩溃。我知道在许多情况下可以获取文件的路径,但在许多其他情况下是不可能的,并且我也知道可以仅复制文件(这里),但这不是一个好的解决方案,因为即使已经访问到文件,它也可能很大并占用很多空间。
我的尝试
库使用文件的两个位置:
在"K4LVideoTrimmer"文件中,在"setVideoURI"函数中,只需获取文件大小即可显示。在这里,基于Google的文档,解决方案非常简单:
在“TrimVideoUtils”文件中,在调用“genVideoUsingMp4Parser”函数的“startTrim”中,它通过以下方式调用“mp4parser”库:public void setVideoURI(final Uri videoURI) { mSrc = videoURI; if (mOriginSizeFile == 0) { final Cursor cursor = getContext().getContentResolver().query(videoURI, null, null, null, null); if (cursor != null) { int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE); cursor.moveToFirst(); mOriginSizeFile = cursor.getLong(sizeIndex); cursor.close(); mTextSize.setText(Formatter.formatShortFileSize(getContext(), mOriginSizeFile)); } } ...
- 有没有办法克服这个问题?
- 也许有一个更好的替代这个修剪库的选择,同样是宽容的(比如Apache2/MIT许可证)?一个没有这个问题的选择?或者甚至是Android框架自身的东西?我认为MediaMuxer类可以帮助解决这个问题(就像这里所写的那样),但我认为它可能需要API 26,而我们需要处理API 21及以上的版本...
Movie movie = MovieCreator.build(new FileDataSourceViaHeapImpl(src.getAbsolutePath()));
它说他们使用来自“mp4parser”库的FileDataSourceViaHeapImpl
来避免在Android上出现OOM,因此我决定继续使用它。
问题是,它有四个构造函数,每个都需要一些文件变体:File、filePath、FileChannel、FileChannel+fileName。
问题
也许可以实现FileChannel
并模拟真实的文件,通过使用ContentResolver
和Uri
来完成?我猜这可能是可能的,即使意味着需要在需要时重新打开InputStream...
如果您想查看我所做的工作,可以在此处克隆项目https://github.com/AndroidDeveloperLB/VideoTrimmer/。只需知道它不会进行任何修剪,因为“K4LVideoTrimmer”文件中的代码已被注释掉:
//TODO handle trimming using Uri
//TrimVideoUtils.startTrim(file, getDestinationPath(), mStartPosition, mEndPosition, mOnTrimVideoListener);
编辑:
我认为通过使用不同的修剪方案,我已经找到了解决方案,并在这里写了一些内容,但不幸的是它无法处理一些输入视频,而mp4parser
库可以处理它们。
请告诉我是否可以修改mp4parser
以处理这样的输入视频,即使它来源于Uri而不是文件(而不是仅将其复制到视频文件中的变通方法)。