Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Get filenames for photos from camera roll
-
In Pythonista 2, see topic
I already used this way to get the filename of an asset:str(ObjCInstance(photos.get_assets()[0]).valueForKey_('filename'))
and of course also
str(ObjCInstance(photos.get_assets()[0]).valueForKey_('orientation'))
-
-
-
JonB (and cvp),
I'm using the information you provided above as a means of copying video files over ftp. The asset "get_image_data" doesn't work.
Everything you've mentioned above works just fine. I even open the video file in binary read mode "rb" successfully (no exceptions), however, when I hand the opened file object on to ftplib's "ftp.storbinary" method I get the following error: ErrNo 2: No such file or directory: 'IMG_0463.MOV'. I find it interesting that the same file object opened just fine using "open", but there is an error when using storbinary.Am I missing something, or is there something special about these files that is super-top-secret that we aren't supposed to be able to do with these files? If so, can you recommend another method or line-of-thought?
Thanks again!
-
Just to be sure, did you copy the photo as a local file and did you change current directory before the ftp command?
file_path = os.path.expanduser('~/Documents/'+local_file_folder) os.chdir(file_path) local_file = open(file_name,'rb') ftp.storbinary('STOR '+server_file,local_file,blocksize=8192) local_file.close()
-
cvp,
No, I did not copy the file locally. Since I had the filename I figured I would open it and use it. That is beginning to sound naive.
Does the step-by-step process have to look something like this:- Get video filename
- Open video file.
- Save the video file someplace local (to the app/sandbox).
- Close the video file.
- Re-open the newly created video file in local-space and then hand that local-space video file to FTP
Is this close? If so, is there a better way? If not... gadzooks.
Thanks for putting up with my inane questions.
Bill -
I think it should work so...
The asset property filename is only a text (metadata,Exif), it isn't the real name of the file...
-
you should be able to pass the BytesIO object from get_image_data directly to storbinary. No opening it, reading it, etc
-
You're surely right but it is still a copy from the camera roll to a Pythonista memory area (not a file, but is it a difference between a file and an object?) and after that a transfer to FTP.
I think that @billbris hoped a direct transfer from the camera roll file to FTP. -
import photos from objc_util import * from ftplib import FTP import console p = photos.pick_asset(assets=photos.get_assets(media_type='video')) file_name = str(ObjCInstance(p).valueForKey_('filename')) b = p.get_image_data() try: ftp = FTP('Server') #connect ftp.encoding = 'utf-8' ftp.login('User','pwd') ftp.storbinary('STOR '+file_name,b) ftp.close() except Exception as e: console.alert('Error ',str(e),'ok',hide_cancel_button=True)
-
I don't think we have access to the original file, even through objc. Maybe I am wrong -- does someone have an example where you can directly
open
a full path provided by an asset (in ObjC)? my attempts to do that recently gave me access denied errors. -
When we share a file, we have access to read it without being authorized to remove or rename it.
-
I follow this for assets of type image (re: photos), however, this method just doesn't work for video.
Yes, I was attempting to open the video using the filename, and then use that binary file object as the direct source of sending it via FTP to the server. Although I can open the video file by name the FTP server says it cannot find the file of the same name.
Example:
video_filename = str(ObjCInstance(asset).filename())
video_file_object = open(video_filename, 'rb') #this is succesful
ftp.storbinary("STOR "+video_target_filename, video_file_object) #video file object has read method so it should workThis results in a file not found error for the video_filename.
My overall question is what is the preferred/best method of copying a video file via FTP since get_image_data doesn't work?
-
Did you try the little script I posted just before?
It works
File name is only a name, a string, not a file, thus you can't send it!
your line is just an open, not a read and close thus the file is not yet written.
Thus the file does not exist and your ftp command will give this error.
But my script, as adviced by @JonB , does not need to really write a file before sending it via FTP.
Please try my script with your videos and you'll see the .mov on your serverIf you want to work through a file, you need to create the file, that will say write the asset to a file, before it can be opened in read for ftp send.
In summary:
- a photo/video of the camera roll is a file which you can read via photos asset into a Pythonista local object, the real name of this file is not the filename value
- filename is a metadata of the asset, and just a string in Pythonista
- if you want, you can create a Pythonista local file containing the bytes of this object, and you can give to this file any name you want, and by example the filename string
- you can send to your ftp server, either directly the object (my script) or a file that you need first to create locally (open for writing, write, close)
loc_file = open(file_name,mode='wb') loc_file.write(b.getvalue()) loc_file.close()
-
cvp,
Thanks for the input. I used your script from above and I get the same problem that I've grown to expect. It seems that get_image_data only returns the first frame (or something). A file with the correct name is created on the FTP server just as expected, however, the contents are not that of a valid video (.MOV). In fact the file size is approximately 110Kb on my Windows machine and that is rather small for a 30 second video.
This brings me back to the original problem.
I will try copying the video file from the photo assets to a sandbox/local directory and then pass that on to the FTP server.
-
The problem is that you DO NOT GET even read access to video files unless you specifically request it. The following fails
p = photos.pick_asset(assets=photos.get_assets(media_type='video')) file_name = str(ObjCInstance(p).valueForKey_('filename')) P=ObjCInstance(p) try: print(str(P.pathForOriginalFile())) open(str(P.pathForOriginalFile()),'rb') except PermissionError: print('Could not open')
(The other examples people used above tried to read files in the script folder, which will certainly fail unless you have already created such a file!)
Now, it turns out you can get read access to the file, but it takes a few extra steps:
https://gist.github.com/de01d929d3477a4c8e7ae9517d5b3d70With this I was able to read a few dozen moviews taken in my ipad. Note video files are big, so if you want to read to a file (though not needed...) you should read in chunks.
-
@billbris sorry, I did not understand your real problem of only one frame, and I did not check the size of my file on FTP server, shame on me
@jonb and one more time, Thanks to the biggest guru of this forum. I'm not sure that I will still try to help here 😢
In my example, I never read a file, I write it, thus I did not get any error, it I agree that only one frame has been written. -
@cvp: No problem, I appreciate the time and effort.
@jonb: The linked code worked just as advertised. I have no experience, yet, with the real internals of iOS, nor with video files. I'm sure that there is a very good reason why videos are handled so much differently than pictures, but at some level they are all just files. Regardless, the code works and I can incorporate it into my existing solution. Thanks for the mind share! -
So... in the end, how long does it take to ftp the 1600 files?
-
@ccc: Once I get everything for the video transfer in place, I will let you know. At this point, I have made no attempt at anything other than functionality. Also, of the 1600+ files, only 32 or so are videos. I will post results when I'm finished.