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().
Related
I have following Dart code and I am trying to make reading the file buffered. Just like Java's BufferedReader or C++ ifstream. Is there such functionality? I cannot even find buffer mentioned in file.dart nor file_impl.dart. If I understood my debugging correctly, it seems that Dart is reading the whole file at once.
So could anybody help me make it buffered or point me in right direction where the buffer is?
final file = File(join(documentsDirectory, "xxx.txt"));
final List<String> lines = await file.readAsLines(); //file.readAsLinesSync()
lines.forEach((line) {
....
});
Use file.openRead(). This will return a Stream of bytes. If you want to read as characters, transform the stream using the appropriate decoder (probably utf8).
As it says, you must read the stream to the end, or cancel it.
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.
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);
}
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;
}
I need to capture frame by frame from a video stored in my sd card of the Android device (in this case my emulator). I am using Android and OpenCV through NDK. I pushed manually the file "SinglePerson.avi" inside the sdcard through file explorer of DDBS (eclipse) and I used the code below to read the file:
JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_Sample4Mixed_VideoProcessing(JNIEnv*, jobject)
{
LOGI("INSIDE VideoProcessing ");
CvCapture* capture = cvCaptureFromAVI("/mnt/sdcard/SinglePerson.avi");
IplImage* img = 0;
if(!cvGrabFrame(capture)){ // capture a frame
LOGI("Inside the if");
printf("Could not grab a frame\n\7");
exit(0);
}
img=cvRetrieveFrame(capture);// retrieve the captured frame
cvReleaseCapture(&capture);
}
The problem is that cvGrabFrame(capture) results always false.
Any suggestion to correctly open the video and grab the frames?
Thanks in advance
Some versions of OpenCV (in package opencv2) build without video support. If it is your case you have to enable "-D WITH_FFMPEG=ON" in pkg's Makefile and recompile.
Look at "Displaying AVI Video using OpenCV" tutorial:
"You may need to ensure that ffmpeg has been successfully installed in order to allow video encoding and video decoding in different formats. Not having the ffmpeg functionality may cause problems when trying to run this simple example and produce a compilation errors".
Also check path in cvCaptureFromAVI for correctness.
Hope this will help!
The behavior you are observing is probably due to cvCaptureFromAVI() failing. You need to start coding safely and check the return of the calls you make:
CvCapture* capture = cvCaptureFromAVI("/mnt/sdcard/SinglePerson.avi");
if (!capture)
{
printf("!!! Failed to open video\n\7");
exit(0);
}
This function usually fails for 2 reasons:
When it's unable to access the file (due to wrong filesystem permissions);
Missing codecs on the system (or the video format is not supported by OpenCV).
If you are new to OpenCV, I suggest you test your OpenCV code on a desktop (PC) first.