2

I am using the 0.4.2 version of the jar in my project to record video an upload it. The file name returned from SimpleCameraHost.getVideoFileName() is wrong on my Nexus 4.

It looks like the file name is time stamped and I have a file Video_20131113_223704.mp4 on the device but the method returned Video_20131113_223708.mp4 off by 4 seconds?

Is there something I should be doing to get a proper filename?

P.S. I would add a cwac-camera tag if I had enough rep...

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
Jeff
  • 2,198
  • 3
  • 21
  • 38
  • "It looks like the file name is time stamped and I have a file Video_20131113_223704.mp4 on the device but the method returned Video_20131113_223708.mp4 off by 4 seconds?" -- if you only have one video file, you only have one video filename, not two, because a file cannot have two names. Hence, I do not understand the quoted sentence. – CommonsWare Nov 14 '13 at 11:20
  • Starting and stopping record in your CameraFrament class created a file ending with _223704.mp4 on my device. Then calling into the SimpleCameraHost method getVideoFileName() in my subclass returned a videoFileName ending with _223708.mp4 so when I tried to upload the file returned from your method it failed becuase that file doesn't exist. I was confused why SimpleCameraHost would return a filename that was 'close' and wondered if there was a timing issue... – Jeff Nov 14 '13 at 13:17
  • Would you please tell us how did you solve this issue. I am having the same thing and can't seem to find a way so far. Thank you – Abdellah Benhammou Mar 02 '14 at 02:21

2 Answers2

2

Starting and stopping record in your CameraFrament class created a file ending with _223704.mp4 on my device

That's because getVideoPath() is designed to be called by CameraView, to generate the filename to be used for the video. getVideoFileName(), in turn, is used by getVideoPath(). This has to be done before the video starts recording.

Then calling into the SimpleCameraHost method getVideoFileName() in my subclass returned a videoFileName ending with _223708.mp4 so when I tried to upload the file returned from your method it failed becuase that file doesn't exist.

You don't call getVideoFileName(), you implement it. The expectation is that if you are using the stock implementation, you do not need the filename in your own code. If you need the filename, override getVideoFileName() (and/or related methods, like getVideoPath()), return what you want (which could very well be whatever the superclass returns), and hold onto the result for later use.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • I see how I was using the SimpleCameraHost wrong. The CameraFragment doesn't have an accessor for the file name and directory that it got from the CameraHost so if you aren't the provider of the CameraHost there isn't any way to get it. I mistakenly thought getVideoFileName in the CameraHost would return the one the recorder was using. – Jeff Nov 14 '13 at 19:50
  • @JeffAlexander: No, that data is fairly transient, just used for the one recording operation. I could cache it and return stuff as `getLastVideoFileName()`, but I am unconvinced of the value. – CommonsWare Nov 14 '13 at 22:08
  • Well you do go to the trouble of finding a good location and a nicely time stamped file name by default but no way to get it out of the CameraFragment... – Jeff Nov 15 '13 at 16:33
  • @JeffAlexander: The problem is race conditions, which is a frequent issue with `getLast...()` types of methods -- how do you know that `getLastVideoFileName()` is not for some subsequent operation that happened to be requested before you got around to calling `getLastVideoFileName()`?. It is likely that I need to start passing around some `CameraTransaction` that represent a specific operation, where these names are stored: https://github.com/commonsguy/cwac-camera/issues/67 In the meantime, the recipe in my answer should serve as a workaround. – CommonsWare Nov 15 '13 at 16:50
  • Could anyone of you please write a straight forward answer, I am having the same issue, I want to get the currently being recorded video but I get different names than the one being actually saved in the device. Some solution to get the file name from DemoCameraFragment. – Abdellah Benhammou Mar 02 '14 at 02:15
  • @AbdellahBenhammou: "Could anyone of you please write a straight forward answer" -- I did. "Some solution to get the file name from DemoCameraFragment" -- come up with your *own* path and *own* `SimpleCameraHost` subclass where you return that path from `getVideoPath()`, then also hold onto that path somewhere for the rest of your code to access. Or, override `getVideoPath()`, chain to the superclass to get the generated value, hold onto that path somewhere for the rest of your code to access, and return that path from your overridden `getVideoPath()`. – CommonsWare Mar 02 '14 at 09:31
0

I had the same issue with photos but basically I also thought that getPhotoPath would return the path of the photo I had just taken.

So I read carefully CommonsWare answer, especially the part where he explains how getVideoPath() works.

That's because getVideoPath() is designed to be called by CameraView, to generate the >filename to be used for the video. getVideoFileName(), in turn, is used by getVideoPath(). >This has to be done before the video starts recording.

My understanding is that getVideoPath() is meant to be used by the system rather than by the developper. getVideoPath() calls getVideoFilename() and getVideoDirectory() to build the video path which will later be used by the system to save the video.

That being said, what we need to do (like CommonsWare already said), is to tell the system what path we want our file to be saved at. And we do this by overriding either getVideoFilename(), getVideoDirectory() or getVideoPath().

And once we control that, we can always call getVideoPath() once the video is saved, just to be sure we have the right path.

So since I was happy with the default directory, I just overrode getPhotoFilename() like this :

public class MyCameraHost extends SimpleCameraHost {
private String photoName;
private String extension = ".png";

public MyCameraHost(Context _ctxt) {
    super(_ctxt);
    // TODO Auto-generated constructor stub
}

@Override
protected String getPhotoFilename() {
    // TODO Auto-generated method stub
    return this.photoName + this.extension;
}

public void setPhotoName (String name){
    this.photoName = name;
}
}

And in my camera activity, my takePhoto() method looks like this :

private void takePicture() {
    CameraFragment f = (CameraFragment) getFragmentManager().findFragmentByTag(TAG_CAMERA_FRAGMENT);
    if (f != null && f.isVisible()) {
        cameraHost.setPhotoName("test");
        f.takePicture();
        pictureFile = cameraHost.getPhotoPath();
    }
}

Hope this helps. And thanks CommonWares for this awesome library and your answers to our questions.

JDenais
  • 2,956
  • 2
  • 21
  • 30