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
    7800
    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.
    • 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
                                        • frankL
                                          frankL last edited by

                                          I see that your code works but I'm trying to implement it in a subview and I can't figure out how to use the v.update_interval method.

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

                                            To clarify, I have a button in the main view that plays a video that the user selects from the main view. The button action instantiates a subview that runs the video and presents the slider, play, pause and stop buttons. The slider works to move the video playback manually but otherwise the slider doesn't display the elapsed time of the video. Any insight you can give me would be appreciated.

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