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

      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
                                      • cvp
                                        cvp @frankL last edited by

                                        @frankL said:

                                        how to use the v.update_interval method.

                                        update_interval is not a method but an attribute setting thé interval in seconds between 2 calls to the update méthod in a subclassed view.

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

                                          @frankL said:

                                          Any insight you can give me would be appreciated

                                          It would be easier to help if you post your script.

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

                                            Here is the code. The function with the view for the video player is "play_action".

                                            import ui
                                            import csv
                                            import os
                                            import objc_util
                                            from objc_util import *
                                            
                                            #
                                            def show_list_dialog(items=None, *args, **kwargs):
                                            	items = items or []
                                            	tbl = ui.TableView(**kwargs)
                                            	tbl.data_source = ui.ListDataSource(items)
                                            	my_sel = {'value': None}
                                            	class MyTableViewDelegate (object):
                                            		def tableview_did_select(self, tableview, section, row):
                                            			my_sel['value'] = tableview.data_source.items[row]
                                            			tableview.close()
                                            	tbl.delegate = MyTableViewDelegate()
                                            	tbl.present(style='sheet')
                                            	tbl.wait_modal()
                                            	return my_sel['value']
                                            #
                                            #
                                            def open_video_ref():
                                            	matrix=[]
                                            	my_path=os.path. abspath("dance_video_ref.csv")
                                            	with open(my_path,'r',encoding='utf-8') as reader:
                                            		reader=csv.DictReader(reader)
                                            		for row in reader:
                                            			matrix.append([row['Index'], row['Dance'], row['Instructor'], row['Description'], row['Label'], row['url'], row['level'], row['duration']])
                                            	return matrix
                                            #
                                            #		       MAIN PROGRAM             #
                                            #
                                            
                                            #
                                            w, h = ui.get_screen_size()
                                            h -= 64
                                            bh = bw = 80  # label height and button width
                                            mg = 10  # margin
                                            view = ui.View(name='Dance Lesson Videos', bg_color='#D98880', frame=(0, 0, w, h))
                                            
                                            dance_instructor_value='Select Instructor(s)'
                                            dance_instructor = ui.TextField(frame=(100,15,130,0),border_color='black', border_width=2, text=dance_instructor_value, bordered=True, font=('Arial Rounded MT Bold',15))
                                            dance_instructor.height=30
                                            dance_instructor.width=130
                                            dance_instructor.enabled=False
                                            view.add_subview(dance_instructor)
                                            
                                            #
                                            def instructor_action(sender):
                                            	global dance_matrix
                                            	matrix = open_video_ref()
                                            	priority = int(dance_priority.text)
                                            	dance_matrix = []
                                            	for row in matrix:
                                            		if priority == int(row[6]):
                                            			dance_matrix.append(row)
                                            	instructor_list = ['All']
                                            	for row in dance_matrix:
                                            		instructor = row[2]
                                            		if instructor in instructor_list:
                                            			continue
                                            		else:
                                            			instructor_list.append(instructor)
                                            	f = (0, 0, 400, 300)
                                            	try:
                                            		result = show_list_dialog (instructor_list, frame=f, name='Select an Instructor')
                                            		dance_instructor.text=result
                                            		if dance_instructor.text != 'All':
                                            			new_matrix = []
                                            			for row in dance_matrix:
                                            				if row[2] == dance_instructor.text:
                                            					new_matrix.append(row)
                                            			dance_matrix = new_matrix
                                            		dance_button.enabled=True
                                            		search_dance.text = 'dance name'
                                            	except:
                                            		dance_instructor.text = 'try again'
                                            	pattern_button.enabled=False
                                            	pattern_video.text = 'dance pattern'
                                            	play_button.enabled=False
                                            	return
                                            #
                                            instructor_button = ui.Button(frame=(10,10,130,0),border_color='black', border_width=2, corner_radius = 10, tint_color = 'black', background_color='#EAECEE', action=instructor_action, font=('Arial Rounded MT Bold',18))
                                            instructor_button.title='Instrctr'
                                            instructor_button.width=80
                                            instructor_button.height=40
                                            view.add_subview(instructor_button)
                                            
                                            #
                                            def priority_action(sender):
                                            	matrix = open_video_ref()
                                            	priority_list = []
                                            	for row in matrix:
                                            		priority = row[6]
                                            		if priority in priority_list:
                                            			continue
                                            		else:
                                            			priority_list.append(priority)
                                            	f = (0, 0, 400, 300)
                                            	priority_list.sort()
                                            	result = show_list_dialog(priority_list, frame=f, name='Select Priority')
                                            	dance_priority.text=str(result)
                                            	dance_button.enabled=False
                                            	dance_instructor.text = 'Select Instructor(s)'
                                            	search_dance.text = 'dance name'
                                            	pattern_button.enabled=False
                                            	pattern_video.text = 'dance pattern'
                                            	play_button.enabled=False
                                            	return
                                            #
                                            priority_button = ui.Button(frame=(240,10,130,0),border_color='black', border_width=2, corner_radius = 10, tint_color = 'black', background_color='#EAECEE', action=priority_action, font=('Arial Rounded MT Bold',18))
                                            priority_button.title='Priority'
                                            priority_button.width=80
                                            priority_button.height=40
                                            view.add_subview(priority_button)
                                            
                                            dance_priority_value='0'
                                            dance_priority = ui.TextField(frame=(330,15,130,0),border_color='black', border_width=2, text=dance_priority_value, bordered=True, font=('Arial Rounded MT Bold',15))
                                            dance_priority.height=30
                                            dance_priority.width=30
                                            dance_priority.enabled=False
                                            dance_priority.alignment=ui.ALIGN_CENTER
                                            view.add_subview(dance_priority)
                                            
                                            dance_value='dance name'
                                            search_dance = ui.TextField(frame=(100,65,130,0),border_color='black', border_width=2, text=dance_value, bordered=True, font=('Arial Rounded MT Bold',15))
                                            search_dance.height=30
                                            search_dance.width=130
                                            search_dance.enabled=False
                                            view.add_subview(search_dance)
                                            
                                            #
                                            def dance_action(sender):
                                            	global dance_matrix
                                            	dance_list = []
                                            	for row in dance_matrix:
                                            		dance = row [1]
                                            		if dance in dance_list:
                                            			continue
                                            		else:
                                            			dance_list.append(dance)
                                            	f = (0, 0, 400, 300)
                                            	try:
                                            		result = show_list_dialog(dance_list, frame=f, name='Select a Dance')
                                            		search_dance.text=result
                                            		new_matrix = []
                                            		for row in dance_matrix:
                                            			if row[1] == search_dance.text:
                                            				new_matrix.append(row)
                                            		dance_matrix = new_matrix
                                            		pattern_button.enabled=True
                                            	except:
                                            		search_dance.text = 'try again'
                                            	return
                                            #
                                            dance_button = ui.Button(frame=(10,60,130,30),border_color='black', border_width=2, corner_radius = 10, tint_color = 'black', background_color='#EAECEE', action=dance_action, font=('Arial Rounded MT Bold',18))
                                            dance_button.title='Dance'
                                            dance_button.width=80
                                            dance_button.height=40
                                            dance_button.enabled=False
                                            view.add_subview(dance_button)
                                            
                                            #
                                            pattern_value='dance pattern'
                                            pattern_video = ui.TextView(frame=(100,105,80,0),border_color='black', border_width=2, text=pattern_value, bordered=True, font=('Arial Rounded MT Bold',15))
                                            pattern_video.height=65
                                            pattern_video.width=260
                                            pattern_video.enabled=False
                                            view.add_subview(pattern_video)
                                            #
                                            def pattern_action(sender):
                                            	global found_row
                                            	global dance_matrix
                                            	pattern_list = []
                                            	for row in dance_matrix:
                                            		if row[4] in pattern_list:
                                            			continue
                                            		else:
                                            			pattern_list.append(row[4])
                                            	f = (0, 0, 400, 300)
                                            	result = show_list_dialog(pattern_list, frame=f, name='Select a Pattern')
                                            
                                            	found=False
                                            	for row in dance_matrix:
                                            		if row[4] == result:
                                            			found_row = row
                                            			found=True
                                            			break
                                            	if found:
                                            		pattern_video.text=found_row[3]
                                            		dance_instructor.text = found_row[2]
                                            		play_button.enabled=True
                                            	else:
                                            		pattern_video.text='none found'
                                            	dance_button.enabled=False
                                            	return
                                            #
                                            pattern_button = ui.Button(frame=(10,120,130,30),border_color='black', border_width=2, corner_radius = 10, tint_color = 'black', background_color='#EAECEE', action=pattern_action, font=('Arial Rounded MT Bold',18))
                                            pattern_button.title='Pattern'
                                            pattern_button.width=80
                                            pattern_button.height=40
                                            pattern_button.enabled=False
                                            view.add_subview(pattern_button)
                                            
                                            #
                                            def play_action(sender):
                                            	n = nsurl(found_row[5])
                                            	u=ObjCClass('AVURLAsset'). alloc().initWithURL_options_(n,None)
                                            	i=AVPlayerItem.playerItemWithAsset_(u)
                                            	p=AVPlayer.playerWithPlayerItem_(i)
                                            	videolayer=AVPlayerLayer. playerLayerWithPlayer_(p)
                                            
                                            	v=ui.View(frame=(0,0,500,500))
                                            	V=ObjCInstance(v)
                                            	videolayer.frame=V.bounds()
                                            	V.layer().addSublayer_(videolayer)
                                            	v.present('sheet')
                                            	#
                                            	def play_video_action(sender):
                                            		p.play()
                                            		return
                                            	#
                                            	def pause_video_action(sender):
                                            		p.pause()
                                            		return
                                            	#
                                            	def stop_action(sender):
                                            		p.pause()
                                            		seek(0)
                                            		slider.value = 0
                                            		return
                                            	#
                                            	def add_spaces(sender):
                                            		print('space')
                                            		return
                                            	#
                                            	duration_sec = float(found_row[7])
                                            	slider=ui.Slider(frame=(0,0,v.width,110), background_color = 'lightblue')
                                            
                                            	@on_main_thread
                                            	def seek(t):
                                            		T=c.CMTimeMakeWithSeconds(t,1)
                                            		p.seekToTime_(T,argtypes=[CMTime], restype=None)
                                            	#
                                            	def slider_action(sender):
                                            		seek(sender.value*duration_sec)
                                            	slider.action=slider_action
                                            	v.add_subview(slider)
                                            	#
                                            	v.left_button_items = (((ui.ButtonItem(title='  ', action= add_spaces))),(ui.ButtonItem(title='\u23F8',action=pause_video_action)), ((ui.ButtonItem(title='  ', action= add_spaces))),((ui.ButtonItem(title='\u25B6', action= play_video_action))), ((ui.ButtonItem(title='  ', action= add_spaces))),((ui.ButtonItem(title='\u23F9', action= stop_action))))
                                            	#
                                            	p.play()
                                            
                                            	return
                                            
                                            #
                                            play_button = ui.Button(frame=(10,170,130,30),border_color='black', border_width=2, corner_radius = 10, tint_color = 'black', background_color='#EAECEE', action=play_action, font=('Arial Rounded MT Bold',18))
                                            play_button.title='\u25B6'
                                            play_button.width=80
                                            play_button.height=40
                                            play_button.enabled=False
                                            view.add_subview(play_button)
                                            
                                            
                                            
                                            AVPlayerItem=ObjCClass('AVPlayerItem')
                                            AVPlayer=ObjCClass('AVPlayer')
                                            AVPlayerLayer=ObjCClass('AVPlayerLayer')
                                            import photos
                                            
                                            def pick_asset():
                                                   assets = photos.get_assets(media_type='video')
                                                   asset = photos.pick_asset(assets)
                                                   phasset=ObjCInstance(asset)
                                                   asseturl=ObjCClass('AVURLAsset').alloc().initWithURL_options_(phasset.ALAssetURL(),None)
                                                   return asseturl
                                            #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
                                            
                                            ############
                                            
                                            
                                            
                                            #########################################
                                            nav_view = ui.NavigationView(view)
                                            nav_view.present('sheet')
                                            #########################################
                                            
                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post
                                            Powered by NodeBB Forums | Contributors