Android mp4parser 视频拼接

最近项目里面要用到视频拼接,参考网上的资料决定采用mp4parser进行视频拼接,github上有mp4parser的源码。mp4parser项目很大,这里只用到了视频拼接的部分。这里我封装了一个MyVideoSplicing类,使用时将context,被拼接视频的路径数组videoUris,输出视频文件的名字output三个参数传进去就可以了。

MyVideoSplicing.java

package com.example.recorder;

import android.content.Context;
import android.widget.Toast;

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.AppendTrack;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class MyVideoSplicing {
    private Context context;
    private String[] videoUris;
    private String output;
    public MyVideoSplicing(Context context,String[] videoUris,String output){
        this.context=context;
        this.videoUris=videoUris;
        this.output=output;
    }
    public void videoSplice(){
            //下面是github上mp4parser源码,就可以拼接视频也可以拼接声音
        try {
            List inMovies = new ArrayList();
            for (String videoUri : videoUris) {
                inMovies.add(MovieCreator.build(videoUri));
            }

            List videoTracks = new LinkedList();
            List audioTracks = new LinkedList();

            for (Movie m : inMovies) {
                for (Track t : m.getTracks()) {
                    if (t.getHandler().equals("soun")) {
                        audioTracks.add(t);
                    }
                    if (t.getHandler().equals("vide")) {
                        videoTracks.add(t);
                    }
                }
            }

            Movie result = new Movie();

            if (!audioTracks.isEmpty()) {
                result.addTrack(new AppendTrack(audioTracks.toArray(new Track[audioTracks.size()])));
            }
            if (!videoTracks.isEmpty()) {
                result.addTrack(new AppendTrack(videoTracks.toArray(new Track[videoTracks.size()])));
            }

            Container out = new DefaultMp4Builder().build(result);

            FileChannel fc = new RandomAccessFile(output, "rw").getChannel();
            out.writeContainer(fc);
            fc.close();
            Toast.makeText(context, "拼接成功",
                    Toast.LENGTH_LONG).show();
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(context, "拼接失败",
                    Toast.LENGTH_LONG).show();
        }
    }
}

注:需要将isoviewer-1.0-RC-27作为jar包导入到项目里,这里有点问题,第三方jar包只能用isoviewer-1.0-RC-27。用isoviewer-1.0-RC-35的话拼接出来的只有声音,画面不动,不知道是什么原因。还有用mp4parser拼接出来的文件在原来两段视频拼接处可能会有几帧的画面丢失,但是影响不大

下面是isoviewwe-1.0-RC-27下载地址

http://download.csdn.net/detail/amazinguu/9567246

参考资料

https://github.com/sannies/mp4parser/blob/master/examples/src/main/java/com/googlecode/mp4parser/AppendExample.java

—————————————————————————————————

2016.10.6更新

有些地方没有讲清楚,这里补充一下。isoviewer-1.0-RC-27在android studio里要放到ilbs文件夹下,右键点击add as library后才能用。下面贴出如何使用的demo

效果图:

Android mp4parser 视频拼接_第1张图片

MainActivity.java

package com.example.administrator.videosplicing;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.VideoView;

public class MainActivity extends AppCompatActivity {
    private Button btn_splice,btn_play;
    private VideoView videoView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        videoView= (VideoView) findViewById(R.id.videoView);
        videoView.setMediaController(new MediaController(this));

        btn_splice= (Button) findViewById(R.id.btn_splice);
        btn_splice.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //将录制文件的路径赋给videoUris,使用时改成自己文件路径
                    String[] videoUris = new String[]{
                            "/storage/sdcard0/VideoFolder/video20161006_093619.3gp",
                            "/storage/sdcard0/VideoFolder/video20161006_093626.3gp"
                    };
                String outputname=String.format("/storage/sdcard0/VideoFolder/videoSplice.3gp");
                //自定义视频拼接类
                MyVideoSplicing myVideoSplicing = new MyVideoSplicing(MainActivity.this, videoUris,outputname);
                myVideoSplicing.videoSplice();
            }
        });

        btn_play= (Button) findViewById(R.id.btn_play);
        btn_play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //videoview只支持3gp、MP4、avi,其他格式拼接后的视频请用系统播放器播放
                videoView.setVideoPath("/storage/sdcard0/VideoFolder/videoSplice.3gp");
                videoView.start();
            }
        });
    }
}

activity_main.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.administrator.videosplicing.MainActivity">

    <Button  android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btn_splice" android:text="拼接"/>
    <Button  android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btn_play" android:text="播放"/>
    <VideoView  android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/videoView"/>
LinearLayout>

这里我是用的外部sd卡,要添加下权限


    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

你可能感兴趣的:(Android)