我们希望让用户从任何应用中选择视频,然后将视频剪裁为最多5秒.
为了让Uri被选中,我们让它工作正常(这里有解决方案).
至于修剪本身,我们找不到任何具有许可许可的好图书馆,除了一个名为"k4l-video-trimmer"的图书馆.例如,库"FFmpeg"被认为是非许可,因为它使用GPLv3,这要求使用它的应用程序也是开源的.此外,正如我所读,它需要相当多(约9MB).
可悲的是,这个库(k4l-video-trimmer)很老了,多年没有更新了,所以我不得不把它(这里)分叉,以便很好地处理它.它使用一个名为"mp4parser"的开源库来进行修剪.
问题是,这个库似乎只能处理文件,而不是一个Uri
或者InputStream
,所以即使样本在选择像普通文件一样无法访问的项目时也会崩溃,甚至还有无法处理的路径.我知道在很多情况下可以获得文件的路径,但在许多其他情况下,它不是,我也知道可以只复制文件(这里),但这不是一个好的解决方案,因为文件可能很大并占用大量空间,即使它已经可以访问.
库有两个地方使用文件:
在"K4LVideoTrimmer"文件中,在"setVideoURI"函数中,它只是获取要显示的文件大小.根据Google的文档,这里的解决方案非常简单:
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));
}
}
...
Run Code Online (Sandbox Code Playgroud)在"TrimVideoUtils"文件中,在"startTrim"中调用"genVideoUsingMp4Parser"函数.在那里,它使用以下方法调用"mp4parser"库:
Movie movie = MovieCreator.build(new FileDataSourceViaHeapImpl(src.getAbsolutePath()));
Run Code Online (Sandbox Code Playgroud)
它说他们使用FileDataSourceViaHeapImpl
(来自"mp4parser"库)来避免Android上的OOM,所以我决定继续使用它.
事实是,它有4个CTORS,都期望文件有一些变化:File,filePath,FileChannel,FileChannel + fileName. …
android filechannel inputstream android-contentresolver mp4parser
我已经设法使用NDK版本r5c为Android NDK 编译halfninja ffmpeg脚本.(不幸的是,任何使用早期NDK编译的尝试都会产生一些错误),而且我对整个NDK过程并不是很了解,所以对我来说这有点受欢迎.
他的脚本正在编译ffmpeg版本N-30996-gf925b24(他为脚本执行的具体提交)
继续我的实际应用程序.我设法修剪影片没有问题,现在我需要加入/在使用上这3个环节中的命令的任何和几种组合(将它们连接起来,但任何学尝试链接1,链接2,LINK3)产生的错误,如cat is not valid
,> is undefinined
,unknown option filter_complex
或试图重写一些输入文件.
有没有人知道是否有可能和(怎么做),加入/连接mp4视频(所有相同的编解码器,大小,质量等)使用Android上的半连队编译ffmpeg,或如何编译/获取ffmpeg Android使用最新的源代码?
我也快速尝试了mp4Parser而没有取得多大成功.
最终我试图让这个伪方法起作用:
public static File concatenate(String[] inputPaths, String outputPath){
// ... do stuff do generate ffmpeg commands....
VideoKit v = new VideoKit();
v.run(cmds);
File f = new File(outputPath);
return f;
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试摄取mp4文件并使其成为游戏中时光倒流.它适用于下面的代码.但是,输出文件的帧速率为16*originalFrameRate
.由于我不打算将其作为slow motion
视频播放,我宁愿丢弃这些冗余帧以使输出文件更小.
Movie inputMovie = MovieCreator.build(fileUri);
List<Track> videoTracks = new LinkedList<>();
for (Track track : inputMovie.getTracks()) {
if (track.getHandler().equals("vide")) {
videoTracks.add(track);
}
}
final int speedByFactorOf = 16;
Movie outputMovie = new Movie();
AppendTrack appendedTracks = new AppendTrack(videoTracks.toArray(new Track[videoTracks.size()]));
outputMovie.addTrack(new WrappingTrack(appendedTracks) {
@Override
public long[] getSampleDurations() {
long[] l = super.getSampleDurations();
for (int i = 0; i < l.length; i++) {
l[i] /= speedByFactorOf;
}
return l;
}
});
BasicContainer out = (BasicContainer) new DefaultMp4Builder().build(outputMovie);
FileChannel …
Run Code Online (Sandbox Code Playgroud) 我在我的应用程序中录制了一个来自摄像头的视频并保存在设备存储中.现在我想要反转视频,使其从后向播放.如果视频是10秒,那么第10帧的最后一帧将成为第一帧,它从那里开始播放到第一个第二帧.我想将反转的视频保存在一个文件中.我该怎么办呢?
我正在使用mp4parser,视频需要是同一种类.我正在考虑使用Android的媒体编解码器来解码和编码预卷视频,以适应相机的相同编码输出(正面和背面)任何关于如何做到这一点的建议(如何获得特定的设备编码参数)?
我正在使用mp4parser
合并videos
.从AS运行时,该应用程序运行完美.但如果我手动安装应用程序(传输并运行APK
)或者如果我从中运行它TestFairy
,应用程序崩溃.
当我更新Target Sdk
到时,这种情况就开始发生了Lollipop
.我添加了
`aspectjrt-1.7.3.jar`
`isoparser-1.0-RC-27.jar`
Run Code Online (Sandbox Code Playgroud)
进入libs
我项目的目录.
我也试过以下 versions
`aspectjrt-1.8.5.jar`
`isoparser-1.0-RC-37.jar`
`isoparser-1.0.6.jar`.
Run Code Online (Sandbox Code Playgroud)
不知道它是否正确的方式,但它的工作从Android Studio
然后崩溃TestFairy
或Manual install
.
错误说
com.coremedia.iso.boxes.FileTypeBox
失踪
但它在那里isoparser jar
.
我错过了什么,这是版本问题吗?
我的设备正在运行Android 4.2.2
,如果我的目标SDK
是,这也是一个问题Android 5.0
例外是:
Caused by: java.lang.ClassNotFoundException:com.coremedia.iso.boxes.FileTypeBox
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.coremedia.iso.boxes.FileTypeBox" on path: /data/app/com.myapp.appname-1.apk
Run Code Online (Sandbox Code Playgroud) 我正在使用mp4parser附加两个音频文件.追加已完成,但速度很慢,不知道是什么问题.
在这一行调试器卡住大音频文件,例如大约30分钟的音频文件.
这是代码.
Movie[] inMovies = null;
inMovies = new Movie[]{
MovieCreator.build(fileOne),
MovieCreator.build(fileTwo)};
List<Track> audioTracks = new LinkedList<Track>();
for (Movie m : inMovies) {
for (Track t : m.getTracks()) {
if (t.getHandler().equals("soun")) {
audioTracks.add(t);
}
}
}
Movie result = new Movie();
if (audioTracks.size() > 0) {
result.addTrack(new AppendTrack(audioTracks.toArray(new Track[audioTracks.size()])));
}
Container out = new DefaultMp4Builder().build(result);
String fileName = getFilename();
FileChannel fc = new RandomAccessFile(String.format(fileName), "rw").getChannel();
out.writeContainer(fc);
fc.close();
Run Code Online (Sandbox Code Playgroud)
manifest资源配置文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ehrlite"
android:versionCode="1"
android:versionName="1.0" > …
Run Code Online (Sandbox Code Playgroud) 我在我的项目中使用这两个库:
https://github.com/HemendraGangwar/VideoTrimmingLikeWhatsapp https://github.com/fishwjy/VideoCompressor
两个库都本地导入到我的项目中(即复制它们并将它们添加到项目中)
两个库在单独使用时工作正常,但是当我一起使用时,我得到一些类型的错误Program type already present
,我通过isoparser-1.0.6.jar
从第二个库中删除文件来解决,因为我注意到这两个库使用相同的库'com.googlecode.mp4parser:isoparser'
但具有不同的版本:1.1.21
对于第一个和1.0.6
第二个.
当只使用旧库时,我得到这个代码:
错误:找不到符号类FileDataSourceViaHeapImpl
它现在正在工作,但输出视频(压缩后)没有声音的问题.我怎么解决这个问题?
这是我用来压缩视频的代码(修剪后):
VideoController.getInstance().convertVideo(tmpFile.toString(), dstFile.toString(),
VideoController.COMPRESS_QUALITY_MEDIUM, null);
Run Code Online (Sandbox Code Playgroud)
EDIT1
使用相同的视频在此处使用场景:
VideoTrimmingLikeWhatsapp与verion 1.1.21 =>有效
带有verion 1.0.6 =>的VideoTrimmingLikeWhatsapp不起作用(编译缺失类的错误)
带有1.1.21 =>的VideoCompressor不起作用(没有声音)
VideoCompressor 1.0.6 =>工作
我尝试了很多东西,而且我在这里失去了轨道.我也尝试使用SiliCompressor,它似乎也使用mp4isoparser的1.0.6版本,同样的问题正在发生,输出视频没有声音.我几天前在这里发布了一个问题,但我认为他们不会很快解决这个问题.
我也在这里提交.
我尝试从这里下载mp4parser版本1.1.21 ,并尝试在本地导入它,以便我可以更改包名称,但我不能,因为它Maven
不使用Gradle
.旧版本是一个jar
文件,我需要反编译它,以便我可以搞砸它.我能这样做吗?
我也尝试使用ffmpeg
库,但与mp4isoparser相比,它们都运行得非常慢
我需要旋转视频来调整我的一些需求.我将在下面的列表中解释详细信息.
我正在创建一个像应用程序一样的Vine.我必须录制视频片段,然后将所有部分合并为一个文件.我正在使用mp4解析器库和最新版本1.0-RC-26使用其网站上提供的示例在Android应用程序上执行此操作:此处
如果所有视频具有相同的方向,附加视频示例工作正常但我发现从前置摄像头录制视频的一些问题,因此快速解决方案是将视频方向记录设置为270.此解决方案的不好部分是该段此方向在合并视频上显示错误的方向.
我可能的解决方案是旋转视频以应用我在不同情况下所需的内容,但我没有使用我的代码的工作示例.在互联网上搜索我在这里找到了这样的解决方案.此代码的问题是与上一版本不兼容(它给出了编译错误).我也试图理解库的逻辑,但我没有结果.例如,我尝试使用setMatrix
Movie对象上的指令,但它根本不起作用.
public static void mergeVideo(int SegmentNumber) throws Exception {
Log.d("PM", "Merge process started");
Movie[] inMovies = new Movie[SegmentNumber] ;
//long[] Matrix = new long[SegmentNumber];
for (int i = 1 ; i <= SegmentNumber; i++){
File file = new File(getCompleteFilePath(i));
if (file.exists()){
FileInputStream fis = new FileInputStream(getCompleteFilePath(i));
//Set rotation I tried to experiment with this instruction but is not working
inMovies [i-1].setMatrix(Matrix.ROTATE_90);
inMovies [i-1] = MovieCreator.build(fis.getChannel());
Log.d("PM", "Video " + i + " …
Run Code Online (Sandbox Code Playgroud) 我正在使用mp4Parser isoviewer-1.0-RC-35.jar
来组合使用android MediaRecorder录制的剪辑.通过聆听音轨,剪辑似乎正确组合,但视频保持在一帧上,时间码在播放时保持为零.
媒体记录器创建单个剪辑时的代码
mediaRecorder = new MediaRecorder();
myCamera.lock();
myCamera.unlock();
String clipLocation = file.getAbsolutePath();
_moviePaths.add(clipLocation);
// Please maintain sequence of following code.
// If you change sequence it will not work.
mediaRecorder.setCamera(myCamera);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
if (facingBack) {
mediaRecorder.setOrientationHint(90);
} else {
mediaRecorder.setOrientationHint(270);
}
// Log.v("cam","supported vid sizes: "+
// myCamera.getParameters().getSupportedVideoSizes());
CamcorderProfile profile = CamcorderProfile
.get(CamcorderProfile.QUALITY_720P);
// mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
//mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
// mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setMaxDuration(g.kMaxVideoDurationInMiliseconds);// 15seconds
mediaRecorder.setProfile(profile);
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
mediaRecorder.setOutputFile(path + filename);
mediaRecorder.prepare();
startTimer();
mediaRecorder.start();
}
Run Code Online (Sandbox Code Playgroud)
我用来组合剪辑的方法:
protected void combineClips() throws IOException{
for(int i=0; …
Run Code Online (Sandbox Code Playgroud) mp4parser ×10
android ×8
video ×3
java ×2
ffmpeg ×1
filechannel ×1
inputstream ×1
mediacodec ×1
merge ×1
performance ×1