-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathvideotools.py
130 lines (99 loc) · 3.38 KB
/
videotools.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env python
import skvideo.io
import os,sys
from operator import add
import numpy as np
import boto3
import botocore
import tempfile
from pathlib import Path
import PIL
import s3tools
class Video:
isopen=False
_nframes=None
_fps=None
_dur=None
_pth=None
def __init__(self,pth):
self._pth=s3tools.getpath(pth)
def get_dur(self):
if self._dur is None:
# opencv metadata does not seem reliable for these files
# ffprobe is good for duration
metadata = skvideo.io.ffprobe(self._pth)
self._dur=float(metadata['video']['@duration'])
return self._dur
def get_nframes(self):
if self._nframes is None:
metadata = skvideo.io.ffprobe(self._pth)
self._nframes=float(metadata['video']['@nb_frames'])
return self._nframes
def get_fps(self):
if self._fps is None:
self._fps=self.get_nframes()/self.get_dur()
return self._fps
def open(self):
# here you can set keys and values for parameters in ffmpeg
self.cap= skvideo.io.FFmpegReader(self._pth)
self.currframe=0
self.currtime=0
self.isopen=True
def average_chunk(self,dur,outfn=None):
allimg=np.asarray(0.)
nframes=0
while (self.currtime+dur)>(self.currframe/self._fps):
if self.currframe<self.nframes:
img = self.cap.next()
self.currframe+=1
allimg=np.add(allimg,img)
nframes += 1
else:
self.isopen=False
break
# Get average
meanimg= np.divide(allimg,nframes)
self.currtime=self.currtime+dur
# Write out if requested to
if not outfn is None:
skvideo.io.vwrite(outfn, meanimg)
return meanimg
def select_frames(self, dur, outfn=None):
'''
Picks a single frame and skips frames for "dur" from it
'''
nframes = 0
firstimg=None
while (self.currtime + dur) > (self.currframe / self._fps):
if self.currframe<self._nframes:
img = self.cap.next()
if nframes==0:
firstimg={'currtime': self.currtime, 'currframe': self.currframe, 'img': img}
else:
self.isopen = False
self.currframe += 1
nframes += 1
# Get average
self.currtime = self.currtime + dur
# Write out if requested to
if not outfn is None and not firstimg is None:
skvideo.io.vwrite(outfn, firstimg['img'])
return firstimg
def get_next_frame(self, outfn=None,skipcurrtimeupdate=False):
try:
img = next(self.cap.nextFrame())
if not isinstance(img,PIL.Image.Image):
img=PIL.Image.fromarray(img)
except:
self.isopen=False
img=None
self.currframe += 1
# Get average
if skipcurrtimeupdate:
self.currtime=None
else:
self.currtime = self.currtime + 1/self.get_fps()
# Write out if requested to
# if not outfn is None:
# cv2.imwrite(outfn, img)
return img