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.


    how to get last video on iphone?

    Pythonista
    3
    41
    7799
    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.
    • frankL
      frankL last edited by

      I've been looking at the photos module documentation and have managed some rudimentary scripts to access images on my iphone. The documentation seems to indicate that videos can also be accessed but when I've tried:

      videos = photos.get_assets(media_type='video', include_hidden=True)
      last_video = videos[-1]
      video = last_video.get_ui_image()
      video.show()

      It only displays the last photo, not video. What am I doing wrong? Thanks

      cvp 2 Replies Last reply Reply Quote 0
      • cvp
        cvp @frankL last edited by

        @frankL said:

        video = last_video.get_ui_image()

        This line implies that you take only one image.
        What do you want to do?
        Copy a video from the camera roll to....?

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

          @frankL this copies picked video to Pythonista local files

          import photos
          from objc_util import *
          import time
          import shutil
          import os
          	
          videos = photos.get_assets(media_type='video')
          assets = photos.pick_asset(assets=videos,multi=True)
          #print(dir)
          
          options=ObjCClass('PHVideoRequestOptions').new()
          options.version=1	#PHVideoRequestOptionsVersionOriginal, use 0 for edited versions.
          image_manager=ObjCClass('PHImageManager').defaultManager()
          
          handled_assets=[]
          
          def handleAsset(_obj,asset, audioMix, info):
          	A=ObjCInstance(asset)
          	'''I am just appending to handled_assets to process later'''
          	handled_assets.append(A)
          	'''
          	# alternatively, handle inside handleAsset.  maybe need a threading.Lock here to ensure you are not sending storbinaries in parallel
          	with open(str(A.resolvedURL().resourceSpecifier()),'rb') as fp:
          		fro.storbinary(......)
          	'''
          	
          handlerblock=ObjCBlock(handleAsset, argtypes=[c_void_p,]*4)
          
          for A in assets:
          	#these are PHAssets
          	image_manager.requestAVAssetForVideo(A, 
          						options=options, 
          						resultHandler=handlerblock)
          						
          while len(handled_assets) < len(assets):
          	'''wait for the asynchronous process to complete'''
          	time.sleep(1)
          
          for A in handled_assets:
          	url = str(A.resolvedURL().resourceSpecifier())
          	local = os.path.basename(url)
          	print(url)
          	shutil.copy(url,local)
          
          1 Reply Last reply Reply Quote 0
          • frankL
            frankL last edited by

            Thank you. That allows me to find my videos, but how do I play them either in the console or otherwise?

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

              @frankL try this @JonB ' s player

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

                The player works perfectly. If I wanted to pick a video and get it's url and save that for later, how would I pass that url to the player directly and not from the pick_asset call?

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

                  @frankL in the script, you can print(u) to get an url like assets-library://asset/asset.MOV?id=C03ABFB4-08F3-4A00-B626-BB9A01B293B2&ext=MOV

                  So, if you save this string in a file, you can reuse with these lines

                  url = nsurl('assets-library://asset/asset.MOV?id=C03ABFB4-08F3-4A00-B626-BB9A01B293B2&ext=MOV')
                  u=ObjCClass('AVURLAsset').alloc().initWithURL_options_(url,None)
                  i=AVPlayerItem.playerItemWithAsset_(u)
                  p=AVPlayer.playerWithPlayerItem_(i)
                  videolayer=AVPlayerLayer.playerLayerWithPlayer_(p)
                  
                  1 Reply Last reply Reply Quote 0
                  • frankL
                    frankL last edited by

                    I printed the url, substituted it as you suggested, but after:

                    url = nsurl('assets-library://asset/asset.MOV?id=7C43F2B6-68DB-4314-80A7-34C6F92E8C8A&ext=MOV')
                    C03ABFB4-08F3-4A00-B626-BB9A01B293B2&ext=MOV')
                    u=ObjCClass('AVURLAsset').alloc().initWithURL_options_(url,None)

                    print(u) returns None
                    I must still be missing something.

                    cvp 2 Replies Last reply Reply Quote 0
                    • cvp
                      cvp @frankL last edited by cvp

                      @frankL ok, sorry, print(u) is erroneous, I wanted to say print(url), what you did.
                      But now you have the url as a string, you can save it where you want and read it later to only
                      Display via some script lines of my post, without passing via pick

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

                        @frankL this script only plays a video. Up to you to save the url in a file in the initial pick script and to read it and play in this script

                        from objc_util import *
                        AVPlayerItem=ObjCClass('AVPlayerItem')
                        AVPlayer=ObjCClass('AVPlayer')
                        AVPlayerLayer=ObjCClass('AVPlayerLayer')
                        
                        url = nsurl('assets-library://asset/asset.MOV?id=C03ABFB4-08F3-4A00-B626-BB9A01B293B2&ext=MOV')
                        u=ObjCClass('AVURLAsset').alloc().initWithURL_options_(url,None)
                        i=AVPlayerItem.playerItemWithAsset_(u)
                        p=AVPlayer.playerWithPlayerItem_(i)
                        videolayer=AVPlayerLayer.playerLayerWithPlayer_(p)
                        
                        import ui
                        v=ui.View(frame=(0,0,500,500))
                        V=ObjCInstance(v)
                        videolayer.frame=V.bounds()
                        V.layer().addSublayer_(videolayer)
                        v.present('sheet')
                        
                        p.play()
                        
                        1 Reply Last reply Reply Quote 1
                        • frankL
                          frankL last edited by

                          That works perfectly, thank you.
                          Is there some documentation on video players and objc that you could point me to so that I can get a better understanding of how this all works?

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

                            @frankL standard Apple doc contains all (and more) info needed, good luck

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

                              Thank you. I had only been looking at Pythonista 3 documentation and just recently came across the photos module. Photos doesn't appear to support much in the way of videos.
                              I appreciate all of your help.

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

                                Is there a simple way to add controls to the player such as pause, play, etc.?

                                cvp 2 Replies Last reply Reply Quote 0
                                • cvp
                                  cvp @frankL last edited by

                                  @frankL try this

                                  from objc_util import *
                                  AVPlayerItem=ObjCClass('AVPlayerItem')
                                  AVPlayer=ObjCClass('AVPlayer')
                                  AVPlayerLayer=ObjCClass('AVPlayerLayer')
                                  
                                  url = nsurl('assets-library://asset/asset.MOV?id=71F89028-7FA0-4C53-B6AD-6659BC8458D8&ext=MOV')
                                  u=ObjCClass('AVURLAsset').alloc().initWithURL_options_(url,None)
                                  i=AVPlayerItem.playerItemWithAsset_(u)
                                  p=AVPlayer.playerWithPlayerItem_(i)
                                  videolayer=AVPlayerLayer.playerLayerWithPlayer_(p)
                                  
                                  import ui
                                  v=ui.View(frame=(0,0,500,500))
                                  V=ObjCInstance(v)
                                  videolayer.frame=V.bounds()
                                  V.layer().addSublayer_(videolayer)
                                  v.present('sheet')
                                  
                                  p.play()
                                  
                                  bplay = ui.ButtonItem()
                                  bplay.title = 'play'
                                  def b_play_action(sender):
                                  	p.play()
                                  bplay.action = b_play_action
                                  
                                  bpause = ui.ButtonItem()
                                  bpause.title = 'pause'
                                  def b_pause_action(sender):
                                  	p.pause()
                                  bpause.action = b_pause_action
                                  
                                  v.right_button_items = (bplay, bpause)
                                  
                                  1 Reply Last reply Reply Quote 0
                                  • cvp
                                    cvp @frankL last edited by

                                    @frankL you can even find an example of a slider in the minimal à player Of @JonB

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

                                      Thank you. All that is running correctly now. How can I update the slider to indicate the elapsed time status of the video? The Apple documentation is very difficult to understand.

                                      cvp 3 Replies Last reply Reply Quote 0
                                      • cvp
                                        cvp @frankL last edited by

                                        @frankL said:

                                        How can I update the slider to indicate the elapsed time status of the video

                                        from objc_util import *
                                        import ui
                                        AVPlayerItem=ObjCClass('AVPlayerItem')
                                        AVPlayer=ObjCClass('AVPlayer')
                                        AVPlayerLayer=ObjCClass('AVPlayerLayer')
                                        
                                        url = nsurl('assets-library://asset/asset.MOV?id=71F89028-7FA0-4C53-B6AD-6659BC8458D8&ext=MOV')
                                        u=ObjCClass('AVURLAsset').alloc().initWithURL_options_(url,None)
                                        i=AVPlayerItem.playerItemWithAsset_(u)
                                        p=AVPlayer.playerWithPlayerItem_(i)
                                        videolayer=AVPlayerLayer.playerLayerWithPlayer_(p)
                                        
                                        #define cmtime, for seeking
                                        import ctypes
                                        CMTimeValue=ctypes.c_int64
                                        CMTimeScale=ctypes.c_int32
                                        CMTimeFlags=ctypes.c_uint32
                                        CMTimeEpoch=ctypes.c_int64
                                        class CMTime(Structure):
                                           _fields_=[('value',CMTimeValue),
                                           ('timescale',CMTimeScale),
                                           ('flags',CMTimeFlags),
                                           ('epoch',CMTimeEpoch)]
                                           def __init__(self,value=0,timescale=1,flags=0,epoch=0):
                                              self.value=value
                                              self.timescale=timescale
                                              self.flags=flags
                                              self.epoch=epoch
                                        c.CMTimeMakeWithSeconds.argtypes=[ctypes.c_double,ctypes.c_int32]
                                        c.CMTimeMakeWithSeconds.restype=CMTime
                                        c.CMTimeGetSeconds.argtypes=[CMTime]
                                        c.CMTimeGetSeconds.restype=c_double
                                        
                                        
                                        class MyView(ui.View):
                                        	def __init__(self, *args, **kwargs):
                                        		ui.View.__init__(self, *args, **kwargs)
                                        		self.background_color = 'white'
                                        		
                                        		V=ObjCInstance(self)
                                        		videolayer.frame=V.bounds()
                                        		V.layer().addSublayer_(videolayer)
                                        
                                        		bplay = ui.ButtonItem()
                                        		bplay.title = 'play'
                                        		def b_play_action(sender):
                                        		    p.play()
                                        		bplay.action = b_play_action
                                        		self.update_interval = 0		
                                        		
                                        		bpause = ui.ButtonItem()
                                        		bpause.title = 'pause'
                                        		def b_pause_action(sender):
                                        		    p.pause()
                                        		bpause.action = b_pause_action		
                                        		self.right_button_items = (bplay, bpause)
                                        		
                                        		slider=ui.Slider(frame=(0,0,self.width,20))		
                                        		#sender.superview.name = str(sender.value*duration_sec)
                                        		slider.action=self.slider_action
                                        		slider.bring_to_front()
                                        		self.slider = slider
                                        		self.add_subview(slider)
                                        		
                                        	def update(self):
                                        		s = p.currentTime().a/p.currentTime().b
                                        		self.slider.value = s/duration_sec
                                        
                                        	def slider_action(self, sender):
                                        		self.seek(sender.value*duration_sec)
                                        		
                                        	@on_main_thread
                                        	def seek(self,t):
                                        		T=c.CMTimeMakeWithSeconds(t,1)
                                        		p.seekToTime_(T,argtypes=[CMTime],restype=None)
                                        
                                        v=MyView(frame=(0,0,500,500))
                                        v.present('sheet')
                                        
                                        duration=i.duration()
                                        duration_sec=duration.a/duration.b
                                        #print(duration_sec)
                                        
                                        p.play()
                                        v.update_interval = 0.1	
                                        
                                        
                                        1 Reply Last reply Reply Quote 0
                                        • cvp
                                          cvp @frankL last edited by

                                          @frankL try until

                                          v.update_interval = 1/60	
                                          
                                          1 Reply Last reply Reply Quote 0
                                          • cvp
                                            cvp @frankL last edited by

                                            @frankL Is it what you wanted?

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