omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    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

    Pythonista
    6
    27
    20723
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • JonB
      JonB last edited by ccc

      you should be able to pass the BytesIO object from get_image_data directly to storbinary. No opening it, reading it, etc

      1 Reply Last reply Reply Quote 0
      • cvp
        cvp last edited by cvp

        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.

        1 Reply Last reply Reply Quote 0
        • cvp
          cvp last edited by

          @billbris
          As @JonB said

          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)	
          
          
          1 Reply Last reply Reply Quote 0
          • JonB
            JonB last edited by

            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.

            1 Reply Last reply Reply Quote 0
            • cvp
              cvp last edited by

              When we share a file, we have access to read it without being authorized to remove or rename it.

              1 Reply Last reply Reply Quote 0
              • billbris
                billbris last edited by

                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 work

                This 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?

                1 Reply Last reply Reply Quote 0
                • cvp
                  cvp last edited by cvp

                  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 server

                  If 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()
                  
                  1 Reply Last reply Reply Quote 0
                  • billbris
                    billbris last edited by

                    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.

                    1 Reply Last reply Reply Quote 0
                    • JonB
                      JonB last edited by

                      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/de01d929d3477a4c8e7ae9517d5b3d70

                      With 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.

                      1 Reply Last reply Reply Quote 0
                      • cvp
                        cvp last edited by cvp

                        @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.

                        1 Reply Last reply Reply Quote 0
                        • billbris
                          billbris last edited by

                          @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!

                          1 Reply Last reply Reply Quote 0
                          • ccc
                            ccc last edited by

                            So... in the end, how long does it take to ftp the 1600 files?

                            billbris 1 Reply Last reply Reply Quote 0
                            • billbris
                              billbris last edited by

                              @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.

                              1 Reply Last reply Reply Quote 0
                              • billbris
                                billbris last edited by

                                I have the video copy code in my ftp app. It now copies video files (MOV) over ftp to the server and the videos play perfectly.

                                So, thank you for the pointer. It works.

                                Two questions:

                                1. While attempting to understand the code I found myself stumbling on what was happening with the asset. A group of videos is sent to the script, they are then each processed by standard PHIImageManager into what appears to be an AVAsset rather than a Photos.Asset. I am guessing that is required to get at the video data. What is missing on the server side are the other meta-data (video creation date, etc.) that the AVAsset seems to imply should be there. So, the video data is copied, and nothing else. Ideas on improving this to get everything across, including meta-data.

                                2. This seems to work for a block of video assets, it would be nice to have it handle a single video file as well. Other than packing up a single video file asset into a collection (having only one element) and passing that to the script, does anyone understand what is happening in the OS enough to make the sample gist above work for just one file at a time?

                                Those are picky "wishlist" things, but I am investigation them for completion sake.

                                Finally, once again, thanks to everyone for their amazing pointers and help.

                                1 Reply Last reply Reply Quote 0
                                • ccc
                                  ccc last edited by ccc

                                  @billbris Are you willing to publish your code on GitHub? It is easier to debug Python code than English prose. My bet is that it would be easier for folks to add their code to your code rather than start from scratch.

                                  1 Reply Last reply Reply Quote 0
                                  • JonB
                                    JonB last edited by

                                    The original asset list could instead be passed to pick_asset to choose a single asset, which would then be passed the request..... method. The fundamental method operates on a single asset at a time.

                                    As i mentioned in the comments, it would be possible to do the work inside the request handle, though it might be necessary to have a threading lock (not sure).

                                    As for metadata, AVAsset has a metadata method, also a `creationDate’.

                                    1 Reply Last reply Reply Quote 0
                                    • billbris
                                      billbris @ccc last edited by

                                      @ccc: Sorry for the long delay.

                                      I finally had some time to work on this and just finished running a full batch from my iPad mini.

                                      I copied 1803 files, 32 of which are videos. The total time (not overly scientific, but with a simple take a time at the beginning and end to calculate the delta) was 28minutes and 34 seconds.

                                      I've done nothing to optimize this, but it does work and that's not awful for a first attempt.

                                      Thanks again for the help!

                                      1 Reply Last reply Reply Quote 0
                                      • First post
                                        Last post
                                      Powered by NodeBB Forums | Contributors