I've been working on merging two video. I'm taking the videos from the phone storage and passing them in the form of string. Then this videos are getting merged. I've seen that if I'm merging the videos that is taken from the camera then it is working fine, merging is going good. But as soon as the different video file is taken and taken trying to get merged, it throws an exception says
java.io.IOException: Cannot merge AudioSampleEntry{bytesPerSample=0, bytesPerFrame=0, bytesPerPacket=0, samplesPerPacket=0, packetSize=0, compressionId=0, soundVersion=0, sampleRate=24000, sampleSize=16, channelCount=2, boxes=[com.googlecode.mp4parser.boxes.mp4.ESDescriptorBox@fffffab7]} and AudioSampleEntry{bytesPerSample=0, bytesPerFrame=0, bytesPerPacket=0, samplesPerPacket=0, packetSize=0, compressionId=0, soundVersion=0, sampleRate=22050, sampleSize=16, channelCount=2, boxes=[com.googlecode.mp4parser.boxes.mp4.ESDescriptorBox@fffff9fb]} 08-22 15:59:03.347 27476-27558/in.pinelane.myhovi W/System.err: at com.googlecode.mp4parser.authoring.tracks.AppendTrack.mergeStsds(AppendTrack.java:116) 08-22 15:59:03.347 27476-27558/in.pinelane.myhovi W/System.err: at com.googlecode.mp4parser.authoring.tracks.AppendTrack.<init>(AppendTrack.java:59)
and does not saves any file inside the storage. Also if the heights are different of the video then it gives me this exception and this does not saves any file either
E/isoparser: AppendTrack:height differs
This is my activity you can see the code :
//asynch task to merge the videos in background
class MergeVideos extends AsyncTask<ArrayList<File>, Integer, String>{
@Override
protected String doInBackground(ArrayList<File>... params) {
ArrayList<Movie> inMovies = new ArrayList<>();
for(File file : params[0]){
Movie movie = MovieCreator.build(file.getAbsolutePath());
inMovies.add(movie);
}
List<Track> videoTracks = new LinkedList<Track>();
List<Track> audioTracks = new LinkedList<Track>();
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.size() > 0) {
result.addTrack(new AppendTrack(audioTracks
.toArray(new Track[audioTracks.size()])));
}
if (videoTracks.size() > 0) {
result.addTrack(new AppendTrack(videoTracks
.toArray(new Track[videoTracks.size()])));
}
BasicContainer out = (BasicContainer) new DefaultMp4Builder()
.build(result);
@SuppressWarnings("resource")
FileChannel fileChannel = new RandomAccessFile(String.format(Environment
.getExternalStorageDirectory() + "/MyHoviVideo.mp4"),
"rw").getChannel();
out.writeContainer(fileChannel);
fileChannel.close();
}catch (FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
//retruning the file after successfull completion of the merging
String mFileName = Environment.getExternalStorageDirectory()
.getAbsolutePath();
mFileName += "/MyHoviVideo.mp4";
// = mFileName;
return mFileName;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
progressDialog.dismiss();
Log.e("FILE_PATH===",s);
playVideo(s);
}
}
void playVideo(String play){
mVideoPlayer.setVideoPath(play);
mMediaController = new MediaController(this);
mMediaController.setMediaPlayer(mVideoPlayer);
mVideoPlayer.setMediaController(mMediaController);
mVideoPlayer.setBackgroundColor(Color.TRANSPARENT);
mVideoPlayer.requestFocus();
mVideoPlayer.start();
}
There is a way of doing it and the way is to make the audio and height(resolution) equal before merging. I've looked for FFMPEG but the it is quiet complex to implement in android. I need a good solution for this