how to get last video on iphone?
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()
It only displays the last photo, not video. What am I doing wrong? Thanks
ProbBly the "right_ way to do this is to implement an objcblock that can be passed to the AVPlayer's
JonB, you're over my head on that. If you look at my code, how would I call an update at the top level before the subview is instantiated? And my understanding of objc is very small. I wouldn't know how to implement an objclock to pass to AVPlayer. Suggestions? Thanks.
Alternatively, edit your post and add the
```before and after the code.
the update method is only called at the top level view
I don't think so, I have ui.Views that I simulate as buttons to play a gif in their image, and def update works perfectly.
This post is deleted!last edited by
@frankL the problem is that to can use update method, you have to use a subclass of ui.View, thus, replace all your play_action function by
class MyView(ui.View): def __init__(self, *args, **kwargs): global found_row ui.View.__init__(self, *args, **kwargs) n = nsurl(found_row) u=ObjCClass('AVURLAsset'). alloc().initWithURL_options_(n,None) i=AVPlayerItem.playerItemWithAsset_(u) p=AVPlayer.playerWithPlayerItem_(i) videolayer=AVPlayerLayer. playerLayerWithPlayer_(p) self.p = p self.i = i self.background_color = 'white' V=ObjCInstance(self) videolayer.frame=V.bounds() V.layer().addSublayer_(videolayer) self.update_interval = 0 self.left_button_items = (((ui.ButtonItem(title=' ', action= self.add_spaces))),(ui.ButtonItem(title='\u23F8',action=self.pause_video_action)), ((ui.ButtonItem(title=' ', action= self.add_spaces))),((ui.ButtonItem(title='\u25B6', action= self.play_video_action))), ((ui.ButtonItem(title=' ', action= self.add_spaces))),((ui.ButtonItem(title='\u23F9', action= self.stop_action)))) self.slider=ui.Slider(frame=(0,0,self.width,110), background_color = 'lightblue') self.slider.action=self.slider_action self.slider.bring_to_front() self.add_subview(self.slider) def update(self): duration=self.i.duration() if duration.b == 0: return self.duration_sec=duration.a/duration.b s = self.p.currentTime().a/self.p.currentTime().b self.slider.value = s/self.duration_sec def play_video_action(self,sender): self.p.play() return # def pause_video_action(self,sender): self.p.pause() return # def stop_action(self,sender): self.p.pause() self.seek(0) self.slider.value = 0 return # def add_spaces(self,sender): print('space') return def slider_action(self, sender): self.seek(sender.value*self.duration_sec) @on_main_thread def seek(self,t): T=c.CMTimeMakeWithSeconds(t,1) self.p.seekToTime_(T,argtypes=[CMTime],restype=None) def play_action(sender): global p v=MyView(frame=(0,0,500,500)) v.present('sheet') v.p.play() v.update_interval = 1/60
I replaced the play_action function with your code and I get an error "name '@on_main_thread' is not defined". I'm relatively new to python and haven't tried to create and use "class" so there must be something else I need to add somewhere. What should I do? Thanks
@frankL sure that this line is still in the imports...
from objc_util import *
@frankL I'll be away for 2 hours, sorry. Anyway, if problem still occurs, you can post your code again, included in two lines with
```(you can use the </> button to generate them).
@frankL or if you prefer, I post your full script modified with my little part.
Apparently I had the 'from objc_util import *' after the class MyView(ui.View):
Once I move it up everything works perfectly. I can't thank you enough.
I retired a few years ago and just started learning Python last summer and Pythonista late last fall so I've got a lot to learn and I really appreciate all of your help and the help from everyone on the omz:forum.
Thank you for your help. My video player script is now working very well. I still have one other hurdle that I haven’t figured out how to solve and can use some more help. I have created a csv file to hold the url and some other parameters for each video. I use the parameters in my video player script to find the one I want and play it. The way I got the url for each video was very manual and I would like to eliminate the manual step. I used the video picker from the minimal player to select the video from my iphone and print the AVURLAsset to the console which looks like this:
<AVURLAsset: 0x280d73c00, URL = assets-library://asset/asset.mp4? id=40295592-62D9-4521-9DFF-74A5683BF5EB&ext=mp4>
I then click on it in the console and copy it and then paste:
to another script as part of a list with the other parameters like this:
Dance = 'Tango'
Instructor = 'Lucy'
description = 'Tango 001-Ronde to swivels'
label = 'Ronde to swivels'
n = nsurl(assets-library://asset/asset.mp4? id=40295592-62D9-4521-9DFF-74A5683BF5EB&ext=mp4')
row = (Dance, Instructor, description, label, n)
to create a row. In order to make this work, I have to paste the url into the n=nsurl(‘ url-goes-here ’) that includes the inner single quote marks.
Once I had several rows, I ran a script to write the csv file which I use as my database for videos.
So back to my question, is there a way to grab the AVURLAsset from the video picker
and somehow extract the url from u, and create the row to append to the csv file?
@frankL only, when you pick your asset
def pick_asset(): assets = photos.get_assets(media_type='video') asset = photos.pick_asset(assets) phasset=ObjCInstance(asset) url_str = str(phasset.ALAssetURL())
You store this url_str in your csv
And when you use it
url = nsurl(url_str) asseturl=ObjCClass('AVURLAsset').alloc().initWithURL_options_(phasset.ALAssetURL(),None)