Create video file from images in Android - android

I am reading found many articles and info about creating video from sequence of images. They all recommend to use ffmpeg. The thing is that this pretty complicated. There is simple way to do this without ffmpeg? I need that the result video will be readable to regular video player on the device.

Not sure what you mean by complicated. If you are not very comfortable with native layer then you might use javaCV. It provides java wrapper for ffmpeg among other open source library and works very well.

Possibly, you want to make use of the Movie. The reference is here:
http://developer.android.com/reference/android/graphics/Movie.html
And, a sample example is here:
https://code.google.com/p/animated-gifs-in-android/

You can use JCodec library.
It now supports android too.
You need to download the library and add it in your project.
here is an example of using the library:
SequenceEncoder se = null;
try {
se = new SequenceEncoder(new File(Environment.getExternalStorageDirectory(),
"jcodec_enc.mp4"));
File[] files = yourDirectory.listFiles();
for (int i = 0;i<files.length; i++) {
if (!files[i].exists())
break;
Bitmap frame = BitmapFactory.decodeFile(files[i]
.getAbsolutePath());
se.encodeImage(frame);
}
se.finish();
} catch (IOException e) {
Log.e(TAG, "IO", e);
}

Related

How To: Android OpenCV VideoCapture with File

I am trying to pass a video to the OpenCV VideoCapture class. However when I call the VideoCapture.isOpened() method it always returns false. I have tried two methods:
Saving the video file to the internal memory, context.getFilesDir() => /data/data/package_name/files/VideoToAnalyze/Recording.mp4
and also one to environment.getExternalStorageDirectory() => sdcard/appName/Recording.mp4.
Nothing seems to work here. My question is how do I pass a video file (or what is the correct file path) to a VideoCapture OpenCV object? I've posted some code below as an example. Note that I don't get an error. The file is always found/exists, but when I call isOpened() I always get false.
UPDATE:
So it looks like everyone on the web is saying that OpenCV (I'm using 3.10) is lacking a ffmpeg backend and thus cannot process videos. I'm wondering does anyone know this as a fact ?? And is there a work around. Almost all other alternatives to process videos frame by frame is deathly slow.
String x = getApplicationContext().getFilesDir().getAbsolutePath();
File dir = new File(x + "/VideoToAnalyze");
if(dir.isDirectory()) {
videoFile = new File(dir.getAbsolutePath() + "/Recording1.mp4");
} else {
// handle error
}
if(videoFile.exits(){
String absPath = videoFile.getAbsolutePath();
VideoCapture vc = new VideoCapture();
try{
vc.open(absPath);
} catch (Exception e) {
/// handle error
}
if(!vc.isOpened(){
// this code is always hit
Log.v("VideoCapture", "failed");
} else {
Log.v("VideoCapture", "opened");
.....
Its an old question but nevertheless I had same issue.
Opencv for Android only supports MJPEG codec in AVI container. See this
Just to close this .. I downloaded JavaCV .. included .so files into the android project and then used FFMPEGFrameGrabber.

Reading a video frame by frame with Android OpenCv

I have a set of videos stored in a folder on the android file system.
I would like to read each frame by frame so that i can perform some OpenCv functions on them and then display them in a Bitmap.
I'm not sure how to do this correctly, any help would be appreciated.
You can take a look at Javacv.
"JavaCV first provides wrappers to commonly used libraries by researchers in the field of computer vision: OpenCV, FFmpeg, libdc1394, PGR FlyCapture, OpenKinect, videoInput, and ARToolKitPlus"
To read each frame by frame you'd have to do something like below
FrameGrabber videoGrabber = new FFmpegFrameGrabber(videoFilePath);
try
{
videoGrabber.setFormat("video format goes here");//mp4 for example
videoGrabber.start();
} catch (com.googlecode.javacv.FrameGrabber.Exception e)
{
Log.e("javacv", "Failed to start grabber" + e);
return -1;
}
Frame vFrame = null;
do
{
try
{
vFrame = videoGrabber.grabFrame();
if(vFrame != null)
//do your magic here
} catch (com.googlecode.javacv.FrameGrabber.Exception e)
{
Log.e("javacv", "video grabFrame failed: "+ e);
}
}while(vFrame != null);
try
{
videoGrabber.stop();
}catch (com.googlecode.javacv.FrameGrabber.Exception e)
{
Log.e("javacv", "failed to stop video grabber", e);
return -1;
}
Hope that helps. Goodluck
i know it's to late but any one can use it if he need it
so you can use #Pawan Kumar code and you need to add read permession to your manifest file <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
and you will get it working.
I donĀ“t know about Android but generally you would have to use VideoCapture::open to open your video and then use VideoCapture::grab to get the next frame. See the Documentation of OpenCV for more information on this.
Update:
It seems like camera access is not officially supported for Android at the moment, see this issue on the OpenCV Github: https://github.com/opencv/opencv/issues/11952
You can either try the unofficial branch linked in the issue: https://github.com/komakai/opencv/tree/android-ndk-camera
or use another library to read in the frames and then create an OpenCV image from the data buffer like in this question.

how to read video file and split it into frames

I have this question: how can I load, in Android, a video file stored in my device, and how can I split it into frames?
I'm using IntelliJ and I want to split the video into frames in order to process them with some image processing techniques (with OpenCv for Android library).
You don't strictly need to use OpenCV for this. You can use the MediaMetaDataRetreiver class provided by the SDK. It provides methods to extract metadata from all kinds of media files. You can try something like:
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(file.getAbsolutePath());
imgView.setImageBitmap(retriever.getFrameAtTime(TIME_OFFSET,MediaMetadataRetriever.OPTION_CLOSEST));
where TIME_OFFSET is in microseconds.
Grabbing a video frame in OpenCV is pretty easy. There are lots of examples on OpenCV site. However crucial thing is to set-up opencv on andriod. You can follow this link on getting started with Opencv on andriod.
http://opencv.org/android
Once you have opencv installed on andriod. You can easily load video file and grab frame in Mat structure and then do some processing on it.
Here is the sample one. It will need some modification to run it on andriod. I think you will need to used NDK on andriod for this.
int main(int argc, char*argv[])
{
char *my_file = "C:\\vid_an2\\desp_me.avi";
std::cout<<"Video File "<<my_file<<std::endl;
cv::VideoCapture input_video;
if(input_video.open(my_file))
{
std::cout<<"Video file open "<<std::endl;
}
else
{
std::cout<<"Not able to Video file open "<<std::endl;
}
namedWindow("My_Win",1);
namedWindow("Segemented", 1);
Mat cap_img;
for(;;)
{
input_video >> cap_img;
imshow("My_Win", cap_img);
waitKey(0);
}
return 0;
}

How can i pause voice recording in Android?

My aim is to pause in recording file.
I see in Android developer site its but Media Recorder have not pause option.
Java supports merge two audio file programatically but In android its not work.
Join two WAV files from Java?
And also I used default device audio recorder Apps which is available in all device but in Samsung few devices have not returened recording path.
Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
startActivityForResult(intent,REQUESTCODE_RECORDING);
Any one help for voice recording with pause functionality.
http://developer.android.com/reference/android/media/MediaRecorder.html
MediaRecorder does not have pause and resume methods. You need to use stop and start methods instead.
I had such a requirement in one of my projects, What we done was like make a raw file for saving recorded data in start of recording using AudioRecord , the for each resume we append the data to the same file
like
FileOutputStream fos= new FileOutputStream(filename, true);
here the filename is the name of the raw file and append the new recording data to it.
And when user stop the recording we will convert the entire raw file to .wav( or other) formats. Sorry that i cant post the entire code. Hope this will give you a direction to work.
You can refer my answer here if still have this issue. For API level >= 24 pause/resume methods are available in Android MediaRecorder class.
For API level < 24
Add below dependency in your gradle file:
compile 'com.googlecode.mp4parser:isoparser:1.0.2'
The solution is to stop recorder when user pause and start again on resume as already mentioned in many other answers in stackoverflow. Store all the audio/video files generated in an array and use below method to merge all media files. The example is taken from mp4parser library and modified little bit as per my need.
public static boolean mergeMediaFiles(boolean isAudio, String sourceFiles[], String targetFile) {
try {
String mediaKey = isAudio ? "soun" : "vide";
List<Movie> listMovies = new ArrayList<>();
for (String filename : sourceFiles) {
listMovies.add(MovieCreator.build(filename));
}
List<Track> listTracks = new LinkedList<>();
for (Movie movie : listMovies) {
for (Track track : movie.getTracks()) {
if (track.getHandler().equals(mediaKey)) {
listTracks.add(track);
}
}
}
Movie outputMovie = new Movie();
if (!listTracks.isEmpty()) {
outputMovie.addTrack(new AppendTrack(listTracks.toArray(new Track[listTracks.size()])));
}
Container container = new DefaultMp4Builder().build(outputMovie);
FileChannel fileChannel = new RandomAccessFile(String.format(targetFile), "rw").getChannel();
container.writeContainer(fileChannel);
fileChannel.close();
return true;
}
catch (IOException e) {
Log.e(LOG_TAG, "Error merging media files. exception: "+e.getMessage());
return false;
}
}
Use flag isAudio as true for Audio files and false for Video files.
You can't do it using Android API, but you can save a lot of mp4 files and merge it using mp4parser: powerful library written in Java. Also see my simple recorder with a "pause": https://github.com/lassana/continuous-audiorecorder.

Grab Frame VideoToGif in Android

I'm trying to grab frames from an Video file in android, the only alternative (tha is already compiled an ready for use) is the videoToGif Project. It uses JavaCV, JavaCpp and Java SE inside Android! The final apk is really big, but I'm doing just an academic project...
ERROR
I'm using the follow code:
ModifiedFrameGrabber frameGrabber = new ModifiedFrameGrabber(VIDEO_PATH);
IplImage frame = null;
try
{
frameGrabber.start();
frame = frameGrabber.grab();
} catch(Exception e){...}
byte[] data = frame.getByteBuffer().array();
In the last line I get the error:
Caused by: java.lang.UnsupportedOperationException
at java.nio.DirectByteBuffer.protectedArray(DirectByteBuffer.java:292)
at java.nio.ByteBuffer.array(ByteBuffer.java:144)
at my.package.onCreate(MyClass:x)
Anyone can help me with that? It seems that the proble is in Java API...
Direct NIO buffers don't have an array. Call get() instead of array().

Categories

Resources