Android Studio使用mp4parser进行视频的分割

本文介绍了如何使用开源项目MP4 Parser在Android Studio中进行视频剪辑。详细步骤包括从GitHub下载MP4 Parser库,将其导入项目,并通过VideoClip类设置视频的剪辑起点和终点,实现视频的剪切操作。此外,还提供了VideoHelper工具类用于时间换算。

一 MP4 Parser

1.1 MP4 Parser

MP4 Parser是GitHub上开源的一个视频处理项目。

GitHub链接

1.2功能及使用场

使用该项目能实现视频剪切、视频合并、视频转码等效果。在本博客中,只对视频编辑代码进行讲解,在你的项目中加入开源项目的核心代码后,即可对视频文件进行剪辑处理。

二 下载方法

2.1 下载流程

1) 先进入https://github.com/sannies/mp4parser地址

2) 点击如下图按钮



3) 点击如下图按钮


                         

4) 选择如下图文件下载


5)将下载下来的jar包放入项目的libs文件夹下

6) build.gradle中添加框中的代码



7) AndroidManifest.xml中添加框中的权限



三 视频编辑代码

3.1 源码中的剪辑视频例子

    gitHub仓库源码中的视频剪辑例子

3.2 源码中的剪辑视频代码中文解释

1) 代码块1----对需要剪辑的视频的开始时间和结束时间进行校正

2) 代码块二----根据校正后的时间得到剪辑开始和结束的位置


3) 代码块三----根据剪辑开始和结束的位置保存视频


3.3 基于源码的剪辑代码VideoClip类使用方法

1) 实例化VideoClip类

VideoClip videoClip = new VideoClip();

2) 设置被编辑视频的文件路径

videoClip.setFilePath(url);

3) 设置被编辑的视频输出路径

videoClip.setWorkingPath(out_path);

4) 设置剪辑开始的时间

videoClip.setStartTime(start_time);  

5) 设置剪辑结束的时间

videoClip.setEndTime(end_time);

6) 设置输出的文件名称

videoClip.setOutName(out_name);

7) 调用剪辑并保存视频文件方法(建议作为点击保存时的操作并加入等待对话框)

videoClip.clip();


四 基于源码的视频剪辑代码


VideoClip.java

import com.R;
import com.coremedia.iso.boxes.Container;
import com.googlecode.mp4parser.authoring.Movie;
import com.googlecode.mp4parser.authoring.Track;
import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;
import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator;
import com.googlecode.mp4parser.authoring.tracks.CroppedTrack;

import java.io.File;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
import java.util.LinkedList;
import java.util.List;

/**
 * @ClassName: VideoClip
 * @Description:
 * @version: V2.0
 * @Copyright: X-Force
 * @author: foryou
 * @Date: 2017/2/20 14:24
 */

public class VideoClip {
    private static final String TAG = "VideoClip";
    private String filePath;//视频路径
    private String workingPath;//输出路径
    private String outName;//输出文件名
    private double startTime;//剪切起始时间
    private double endTime;//剪切结束时间


    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }


    public void setWorkingPath(String workingPath) {
        this.workingPath = workingPath;
    }

    public void setOutName(String outName) {
        this.outName = outName;
    }

    public void setEndTime(double endTime) {
        this.endTime = endTime / 1000;
    }

    public void setStartTime(double startTime) {
        this.startTime = startTime / 1000;
    }

    public void clip() {
        try {
            //将要剪辑的视频文件
            Movie movie = MovieCreator.build(filePath);

            List<Track> tracks = movie.getTracks();
            movie.setTracks(new LinkedList<Track>());
            //时间是否修正
            boolean timeCorrected = false;

            //计算并换算剪切时间
            for (Track track : tracks) {
                if (track.getSyncSamples() != null
                        && track.getSyncSamples().length > 0) {
                    if (timeCorrected) {
                        throw new RuntimeException(
                                "The startTime has already been corrected by another track with SyncSample. Not Supported.");
                    }
                    //true,false表示短截取;false,true表示长截取
                    startTime = VideoHelper.correctTimeToSyncSample(track, startTime, false);//修正后的开始时间
                    endTime = VideoHelper.correctTimeToSyncSample(track, endTime, true);     //修正后的结束时间
                    timeCorrected = true;
                }
            }
            //根据换算到的开始时间和结束时间来截取视频
            for (Track track : tracks) {
                long currentSample = 0; //视频截取到的当前的位置的时间
                double currentTime = 0; //视频的时间长度
                double lastTime = -1;    //上次截取到的最后的时间
                long startSample1 = -1;  //截取开始的时间
                long endSample1 = -1;    //截取结束的时间

                //设置开始剪辑的时间和结束剪辑的时间  避免超出视频总长
                for (int i = 0; i < track.getSampleDurations().length; i++) {
                    long delta = track.getSampleDurations()[i];
                    if (currentTime > lastTime && currentTime <= startTime) {
                        startSample1 = currentSample;//编辑开始的时间
                    }
                    if (currentTime > lastTime && currentTime <= endTime) {
                        endSample1 = currentSample;  //编辑结束的时间
                    }
                    lastTime = currentTime;          //上次截取到的时间(避免在视频最后位置了还在增加编辑结束的时间)
                    currentTime += (double) delta
                            / (double) track.getTrackMetaData().getTimescale();//视频的时间长度
                    currentSample++;                 //当前位置+1
                }
                movie.addTrack(new CroppedTrack(track, startSample1, endSample1));// 创建一个新的视频文件
            }

            //合成视频mp4
            Container out = new DefaultMp4Builder().build(movie);
            File storagePath = new File(workingPath);
            storagePath.mkdirs();
            FileOutputStream fos = new FileOutputStream(new File(storagePath, outName));
            FileChannel fco = fos.getChannel();
            out.writeContainer(fco);
            //关闭流
            fco.close();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}



VideoHelper.java(换算时间使用的工具类,可与VideoClip.java合并)


import com.googlecode.mp4parser.authoring.Track;

import java.util.Arrays;

/**
 * @ClassName: VideoHelper
 * @Description:
 * @version: V2.0
 * @Copyright: X-Force
 * @author: foryou
 * @Date: 2017/2/20 14:25
 */

public class VideoHelper {
    /**
     * 换算剪切时间
     */
    public static double correctTimeToSyncSample(Track track, double cutHere,
                                                 boolean next) {
        double[] timeOfSyncSamples = new double[track.getSyncSamples().length];
        long currentSample = 0;
        double currentTime = 0;
        for (int i = 0; i < track.getSampleDurations().length; i++) {
            long delta = track.getSampleDurations()[i];
            if (Arrays.binarySearch(track.getSyncSamples(), currentSample + 1) >= 0) {
                timeOfSyncSamples[Arrays.binarySearch(track.getSyncSamples(),
                        currentSample + 1)] = currentTime;
            }
            currentTime += (double) delta
                    / (double) track.getTrackMetaData().getTimescale();
            currentSample++;
        }
        double previous = 0;
        for (double timeOfSyncSample : timeOfSyncSamples) {
            if (timeOfSyncSample > cutHere) {
                if (next) {
                    return timeOfSyncSample;
                } else {
                    return previous;
                }
            }
            previous = timeOfSyncSample;
        }
        return timeOfSyncSamples[timeOfSyncSamples.length - 1];
    }
}

在博文结尾附上代码与jar包:地址



评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值