I know how images add to the camera roll,usingphotosandphotos.create_image_asset().
However, I donβt know how videos add to it.
I cannot search anymore.Please teach me!
Forum Archive
How videos add to the camera roll
@yutashx
I'm really estonished but this script works as I hoped π
# add a local video file to IOS photos
from objc_util import *
import threading
PHPhotoLibrary = ObjCClass('PHPhotoLibrary')
PHAssetChangeRequest = ObjCClass('PHAssetChangeRequest')
def add_video():
lib = PHPhotoLibrary.sharedPhotoLibrary()
url = nsurl('IMG_6294.MOV') # path to local video file
def change_block():
req = PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL_(url)
def perform_changes():
lib.performChangesAndWait_error_(change_block, None)
t = threading.Thread(target=perform_changes)
t.start()
t.join()
if __name__ == '__main__':
add_video()
Greaaat!Thanks a lot!π
@yutashx Is it not what you asked?
@cvp Iβm sorry. Iβm not still used to using this forum. π
I resolved the problem thanks to you.
Thank you for giving me a great advice!π
I am new and learning now. This code is very useful because I just wanted to add videos to the camera roll. Additionally, I would like to add the videos to my album. I found that AssetCollection.add_assets(assets) enables this. However, I could not find how get the asset of added video using this code. Any way to get the asset ? It would be great if someone could help.
@beans try this
# add a local video file to IOS photos album
from objc_util import *
import threading
PHPhotoLibrary = ObjCClass('PHPhotoLibrary')
PHAssetChangeRequest = ObjCClass('PHAssetChangeRequest')
PHAssetCollectionChangeRequest = ObjCClass('PHAssetCollectionChangeRequest')
def add_video():
lib = PHPhotoLibrary.sharedPhotoLibrary()
url = nsurl('MesTests/mov_bbb.mp4') # path to local video file
def change_block():
req = PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL_(url)
placeholderForCreatedAsset = req.placeholderForCreatedAsset()
album = 'my_album'
albumChangeRequest = PHAssetCollectionChangeRequest.creationRequestForAssetCollectionWithTitle_(album)
albumChangeRequest.addAssets_([placeholderForCreatedAsset])
def perform_changes():
lib.performChangesAndWait_error_(change_block, None)
t = threading.Thread(target=perform_changes)
t.start()
t.join()
if __name__ == '__main__':
add_video()
@cvp : Thank you very much for quick response and useful information. I will try the code on my plan and get back to you.
@cvp I tried the code. I can add the video to specified album. However, the code creates the album every time when adding another video to the album with same name (many 'my_album' are created); can not add the video to existing album. Any information or alternative way ?
@beans sorry for that, I have only tested once. I'll try in the afternoon Brussels time
@beans that should be ok, I hope 
# add a local video file to IOS photos album
from objc_util import *
import threading
PHPhotoLibrary = ObjCClass('PHPhotoLibrary')
PHAssetChangeRequest = ObjCClass('PHAssetChangeRequest')
PHAssetCollectionChangeRequest = ObjCClass('PHAssetCollectionChangeRequest')
PHAssetCollection = ObjCClass('PHAssetCollection')
PHFetchOptions = ObjCClass('PHFetchOptions').alloc()
def add_video():
lib = PHPhotoLibrary.sharedPhotoLibrary()
url = nsurl('MesTests/mov_bbb.mp4') # path to local video file
PHAssetCollectionType = 1 # album
PHAssetCollectionSubtype = 2 # albumregular
album = 'my_album'
NSPredicate = ObjCClass('NSPredicate').predicateWithFormat_argumentArray_("title = %@", [album])
PHFetchOptions.setPredicate_(NSPredicate)
# get number of albums with this name
fetchresult = PHAssetCollection.fetchAssetCollectionsWithType_subtype_options_(PHAssetCollectionType, PHAssetCollectionSubtype, PHFetchOptions)
n_albums = fetchresult.count()
def change_block():
req = PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL_(url)
placeholderForCreatedAsset = req.placeholderForCreatedAsset()
if n_albums == 0:
print('create album',album)
albumChangeRequest = PHAssetCollectionChangeRequest.creationRequestForAssetCollectionWithTitle_(album)
else:
print('existing album',album)
albumChangeRequest = PHAssetCollectionChangeRequest.changeRequestForAssetCollection_(fetchresult.firstObject())
print('add video')
albumChangeRequest.addAssets_([placeholderForCreatedAsset])
def perform_changes():
lib.performChangesAndWait_error_(change_block, None)
t = threading.Thread(target=perform_changes)
t.start()
t.join()
if __name__ == '__main__':
add_video()
@cvp Thank you very much. The code works as expected. Very helpful. Additionally I found another issue through testing the code: the file should be accessible as internal file, the file is only stored in iCloud Drive (not imported to the device as accessible) can not be added. I assume this is reasonable but if any way to start importing from iCloud Drive to the device by the code it will be further helpful. Any ideas ? Sorry for repeated asking.
@beans said:
the file is only stored in iCloud Drive
In which folder? Try to open it as "external folder" in Pythonista files browser

@beans Once you have defined your iCloud Drive folder as external folder in Pythonista, you can get a file with
url = nsurl('/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/MyFolder/mov_bbb.mp4')
@cvp I opened that iCloud folder from EXTERNAL FILES. The folder is shown in EXTERNAL FILES. The files existed in the folder are accessible as '/private/var...', however, the files newly added to that folder are not shown in the folder of EXTERNAL FILES and are not accessible as '/private/var...' The newly added files can be shown using os.listdir('/private/var...'). The file names are shown as '.filename.icloud' (they are not shown in the folder of EXTERNAL FILES). I assume the files are not imported to the device or not synced with EXTERNAL FILES and would like to know if any way to import the files by the code.
@beans it is a known problem: a file not yet locally downloaded is not accessible π’
If you first download it in the Files app, you should be able to access it.
I think there are some topics in this forum about this problem.
Sorry for you
@cvp Thank you for the information. Anyway, the code is very useful.
yeah. it works