I have recorded a video from camera in my app and saved in device storage.Now I want to reverse the video such that it plays from backwards.i.e. if video is of 10 seconds then the last frame at 10th second will become first frame and it starts playing from there to 1st second first frame.I want to save the reversed video in a file.How should i proceed in that?
Thanks to Mick for giving me an idea to use ffmpeg for reversing video.
I have posted code at github for reversing video along with performing other video editing operation using ffmpeg and complete tutorial in my blog post here.
As written in my blog post,
For reversing video,first we need to divide video into segments with duration of 10 seconds or less because reverse video command for ffmpeg will not work for long duration videos unless your device has 32 GB of RAM.
Hence,to reverse a video-
1.Divide video into segments with duration of 10 seconds or less.
2.Reverse the segmented videos
3.Concatenate reversed segmented videos in reverse order.
For dividing video into segments with duration of 6 seconds we can use the below command-
String[] complexCommand = {"-i", inputFileAbsolutePath, "-c:v", "libx264", "-crf", "22", "-map", "0", "-segment_time", "6", "-g", "9", "-sc_threshold", "0", "-force_key_frames", "expr:gte(t,n_forced*6)", "-f", "segment", outputFileAbsolutePath};
Here,
-c:v libx264
encodes all video streams with libx264
-crf
Set the quality for constant quality mode.
-segment_time
time for each segment of video
-g
GOP size
-sc_threshold
set scene change threshold.
-force_key_frames expr:gte(t,n_forced*n)
Forcing a keyframe every n seconds
After segmenting video,we need to reverse the segmented videos.For that we need to run a loop where each segmented video file will be reversed.
To reverse a video with audio(without removing its audio) we can use the below command-
String command[] = {"-i", inputFileAbsolutePath, "-vf", "reverse", "-af", "areverse", outputFileAbsolutePath};
To reverse a video with audio removing its audio we can use the below command-
String command[] = {"-i", inputFileAbsolutePath, "-an", "-vf", "reverse", outputFileAbsolutePath};
To reverse a video without audio we can use the below command-
String command[] = {"-i",inputFileAbsolutePath, "-vf", "reverse", outputFileAbsolutePath};
After reversing segmented videos,we need to concatenate reversed segmented videos in reverse order.For that we sort videos on the basis of last modified file using Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_REVERSE).
Then, to concatenate reversed segmented videos(with audio) we can use the below command-
String command[] = {"-i",inputFile1AbsolutePath,"-i",inputFile2AbsolutePath .....,"-i",inputFileNAbsolutePath,"-filter_complex","[0:v0] [0:a0] [1:v1] [1:a1]...[N:vN] concat=n=N:v=1:a=1 [v] [a],"-map","[v]","-map","[a]", outputFileAbsolutePath};
To concatenate reversed segmented videos(without audio) we can use the below command-
String command[] = {"-i",inputFile1AbsolutePath,"-i",inputFile2AbsolutePath .....,"-i",inputFileNAbsolutePath,"-filter_complex","[0:0] [1:0] [2:0]...[N:0] concat=n=N:v=1:a=0",outputFileAbsolutePath};
Here,
-filter_complex [0:v0] [0:a0] [1:v1] [1:a1]…[N:vN] tells ffmpeg what streams to send to the concat filter.In the above case, video stream 0 [0:v0] and audio stream 0 [0:a0] from input 0,video stream 1 [1:v1] and audio stream 1 [1:v1] from input 1 and so on.
concat filter is used to concatenate audio and video streams, joining them together one after the other.The filter accepts the following options:
n
Set the number of segments. Default is 2.
v
Set the number of output video streams, that is also the number of video streams in each segment. Default is 1.
a
Set the number of output audio streams, that is also the number of audio streams in each segment. Default is 0.