-
Notifications
You must be signed in to change notification settings - Fork 19
/
getframes.py
101 lines (80 loc) · 3.18 KB
/
getframes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# coding: utf-8
'''
get frames of a video, and show them in an imageview.
based on objc code below
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.requestedTimeToleranceAfter = kCMTimeZero;
generator.requestedTimeToleranceBefore = kCMTimeZero;
for (Float64 i = 0; i < CMTimeGetSeconds(asset.duration) * FPS ; i++){
@autoreleasepool {
CMTime time = CMTimeMake(i, FPS);
NSError *err;
CMTime actualTime;
CGImageRef image = [generator copyCGImageAtTime:time actualTime:&actualTime error:&err];
UIImage *generatedImage = [[UIImage alloc] initWithCGImage:image];
[self saveImage: generatedImage atTime:actualTime]; // Saves the image on document directory and not memory
CGImageRelease(image);
}
}
'''
from objc_util import *
import ui,time,os,photos
assets = photos.get_assets(media_type='video')
#print(len(assets))
asset = photos.pick_asset(assets)
duration=asset.duration
#asset.get_image().show()
print(asset.duration)
print(asset.local_id)
#file=os.path.expanduser('~/Documents/capturedvideo.MOV')
#with open(file,'wb') as f:
# f.write(asset.get_image_data().getvalue())
#if not os.path.exists(file):
# raise IOError
phasset=ObjCInstance(asset)
asseturl='assets-library://asset/asset.MOV?id={}&ext=MOV'.format(str(phasset.localIdentifier()).split('/')[0])
asseturl=ObjCClass('AVURLAsset').alloc().initWithURL_options_(nsurl(asseturl),None)
generator=ObjCClass('AVAssetImageGenerator').alloc().initWithAsset_(asseturl)
from ctypes import c_int32,c_uint32, c_int64,byref,POINTER,c_void_p,pointer,addressof, c_double
CMTimeValue=c_int64
CMTimeScale=c_int32
CMTimeFlags=c_uint32
CMTimeEpoch=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.CMTimeGetSeconds.argtypes=[CMTime]
c.CMTimeGetSeconds.restype=c_double
z=CMTime(0,24)
generator.setRequestedTimeToleranceAfter_(z,restype=None,argtypes=[CMTime])
generator.setRequestedTimeToleranceBefore_(z,restype=None,argtypes=[CMTime])
# set up a view to display
root=ui.View(frame=(0,0,576,576))
iv=ui.ImageView(frame=root.bounds)
lbl=ui.Label(frame=(0,0,100,200),flex='LT')
lbl.text='frame'
root.add_subview(iv)
root.add_subview(lbl)
root.present('sheet')
lastimage=None # in case we need to be careful with references
tactual=CMTime(0,1) #return value
t=CMTime(0,1) # timescale is the important bit
for i in range(0,int(duration)):
t.value=i
cgimage_obj=generator.copyCGImageAtTime_actualTime_error_(t,byref(tactual),None,restype=c_void_p,argtypes=[CMTime,POINTER(CMTime),POINTER(c_void_p)])
image_obj=ObjCClass('UIImage').imageWithCGImage_(cgimage_obj)
def setimage():
ObjCInstance(iv).setImage_(image_obj)
lbl.text=str(tactual.value/tactual.timescale)
#delay calls on different thread. for some reason on_main_thread didnt work
ui.delay(setimage,0)
lastimage=image_obj #make sure this doesnt get gc'd
time.sleep(1.0)