post-photo

RxMp4Parser for Android App Developers

More and more Android apps provide video editing based features. This library is not a complete wrapper for the most recent Mp4Parser library. However, it provides a few useful features that are usually used by these apps. If it does fit your application’s needs, feel free to implement those features based on the current implementation. The implemented features’ restrictions are the same as the base library’s restrictions. See: https://github.com/sannies/mp4parser

text

Usage

The base class of the library is RxMp4Parser. This provides the basic functionality for:

Static Functions of RxMp4Parser

text

Operators

These classes can be used with the Observable.lift() function on the specified Observable types. Most of the built in functions in the RxMp4Parser class also uses these operators.

This can be used on an Observable which wraps an Iterable instance. It produces an Observable which wraps a Track implementation (AppendTrack) which contains the received Tracks appended according to their original order.

Observable<List<Track>> audioTracksObservable = ...;
Observable<Track> appendedTrackObservable = audioTracksObservable.lift(new AppendTracks());

Calling this on an Observable instance will produce a new Observable object which contains only part of the original Movie specified by the Operators constructor:

Observable<Movie> movieObservable = ...;
Observable<Movie> croppedMovieObservable = movieObservable.lift(new CropMovie(3.0f, 5.0f));

The first parameter is the start time and the second one is the end time in seconds. The output will contain the Movie part between the two time marker.

This operator is used to mix the supplied Tracks into a Movie instance. It can be used on an Observable<Iterable> instance and will return an Observable object.

Observable<List<Track>> tracksObservable = ...;
Observable<Movie> muxedMovieObservable = tracksObservable.lift(new MuxTracks());

Example

File input = new File(getCacheDir() + "/sample.mp4");
File output = new File(Environment.getExternalStorageDirectory() + "/temp.mp4");
 
RxMp4Parser.concatenateInto(output,
        //The output, where should be stored the resulting Movie object
        output,
        //A full video
        RxMp4Parser.from(input),
        //Cropped video
        RxMp4Parser.crop(input, 8.5f, 13f),
        //Cropped video
        RxMp4Parser.crop(input.getAbsolutePath(), 5, 10),
        //Another full video
        RxMp4Parser.from(input.getAbsolutePath())
            .lift(new CropMovie(18f, 20f))
        )
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<File>() {
            @Override
            public void call(File file) {
                //The process finished, you can use your modified video file!
            }
        }, new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
               //Error occured during the process
            }
        });

Final thoughts

This is not a final, nor a complete implementation of a wrapper, but it is useful for video editing basics. Also, it helps to implement a project specific version when other features are needed. The base library mainly uses synchronous calls for its tasks. In my opinion, the wrapper helps a lot to eliminate the thread handling overhead from an Android App’s base code.

Future

The code used in this post is provided as is. If I’ll have time and need other use-cases from the base library, I’ll extend the functionality. Feel free to contribute to it…

Credits

GitHub

URL: https://github.com/TeamWanari/RxMp4Parser

member photo

He is an Android developer, loves to work with Rx Java and CustomWidgets. Not surprisingly, he codes not only at work, but also in his free time.

Latest post by Tamás Agócs

Life after Google Analytics