Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
a647f577
Commit
a647f577
authored
Sep 15, 2000
by
Jack Jansen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Read a QuickTime movie and return the frames.
parent
344ecdb2
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
276 additions
and
0 deletions
+276
-0
Mac/Lib/videoreader.py
Mac/Lib/videoreader.py
+276
-0
No files found.
Mac/Lib/videoreader.py
0 → 100644
View file @
a647f577
# Video file reader, using QuickTime
#
# This module was quickly ripped out of another software package, so there is a good
# chance that it does not work as-is and it needs some hacking.
#
# Jack Jansen, August 2000
#
import
sys
import
Qt
import
QuickTime
import
Qd
import
Qdoffs
import
QDOffscreen
import
Res
import
MediaDescr
import
imgformat
import
os
# import audio.format
import
macfs
class
VideoFormat
:
def
__init__
(
self
,
name
,
descr
,
width
,
height
,
format
):
self
.
__name
=
name
self
.
__descr
=
descr
self
.
__width
=
width
self
.
__height
=
height
self
.
__format
=
format
def
getname
(
self
):
return
self
.
__name
def
getdescr
(
self
):
return
self
.
__descr
def
getsize
(
self
):
return
self
.
__width
,
self
.
__height
def
getformat
(
self
):
return
self
.
__format
class
_Reader
:
def
__init__
(
self
,
path
):
fsspec
=
macfs
.
FSSpec
(
path
)
fd
=
Qt
.
OpenMovieFile
(
fsspec
,
0
)
self
.
movie
,
d1
,
d2
=
Qt
.
NewMovieFromFile
(
fd
,
0
,
0
)
self
.
movietimescale
=
self
.
movie
.
GetMovieTimeScale
()
try
:
self
.
audiotrack
=
self
.
movie
.
GetMovieIndTrackType
(
1
,
QuickTime
.
AudioMediaCharacteristic
,
QuickTime
.
movieTrackCharacteristic
)
self
.
audiomedia
=
self
.
audiotrack
.
GetTrackMedia
()
except
Qt
.
Error
:
self
.
audiotrack
=
self
.
audiomedia
=
None
self
.
audiodescr
=
{}
else
:
handle
=
Res
.
Handle
(
''
)
n
=
self
.
audiomedia
.
GetMediaSampleDescriptionCount
()
self
.
audiomedia
.
GetMediaSampleDescription
(
1
,
handle
)
self
.
audiodescr
=
MediaDescr
.
SoundDescription
.
decode
(
handle
.
data
)
self
.
audiotimescale
=
self
.
audiomedia
.
GetMediaTimeScale
()
del
handle
try
:
self
.
videotrack
=
self
.
movie
.
GetMovieIndTrackType
(
1
,
QuickTime
.
VisualMediaCharacteristic
,
QuickTime
.
movieTrackCharacteristic
)
self
.
videomedia
=
self
.
videotrack
.
GetTrackMedia
()
except
Qt
.
Error
:
self
.
videotrack
=
self
.
videomedia
=
self
.
videotimescale
=
None
if
self
.
videotrack
:
self
.
videotimescale
=
self
.
videomedia
.
GetMediaTimeScale
()
x0
,
y0
,
x1
,
y1
=
self
.
movie
.
GetMovieBox
()
self
.
videodescr
=
{
'width'
:(
x1
-
x0
),
'height'
:(
y1
-
y0
)}
self
.
_initgworld
()
self
.
videocurtime
=
None
self
.
audiocurtime
=
None
def
__del__
(
self
):
self
.
audiomedia
=
None
self
.
audiotrack
=
None
self
.
videomedia
=
None
self
.
videotrack
=
None
self
.
movie
=
None
def
_initgworld
(
self
):
old_port
,
old_dev
=
Qdoffs
.
GetGWorld
()
try
:
movie_w
=
self
.
videodescr
[
'width'
]
movie_h
=
self
.
videodescr
[
'height'
]
movie_rect
=
(
0
,
0
,
movie_w
,
movie_h
)
self
.
gworld
=
Qdoffs
.
NewGWorld
(
32
,
movie_rect
,
None
,
None
,
QDOffscreen
.
keepLocal
)
self
.
pixmap
=
self
.
gworld
.
GetGWorldPixMap
()
Qdoffs
.
LockPixels
(
self
.
pixmap
)
Qdoffs
.
SetGWorld
(
self
.
gworld
.
as_GrafPtr
(),
None
)
Qd
.
EraseRect
(
movie_rect
)
self
.
movie
.
SetMovieGWorld
(
self
.
gworld
.
as_GrafPtr
(),
None
)
self
.
movie
.
SetMovieBox
(
movie_rect
)
self
.
movie
.
SetMovieActive
(
1
)
self
.
movie
.
MoviesTask
(
0
)
self
.
movie
.
SetMoviePlayHints
(
QuickTime
.
hintsHighQuality
,
QuickTime
.
hintsHighQuality
)
# XXXX framerate
finally
:
Qdoffs
.
SetGWorld
(
old_port
,
old_dev
)
def
_gettrackduration_ms
(
self
,
track
):
tracktime
=
track
.
GetTrackDuration
()
return
self
.
_movietime_to_ms
(
tracktime
)
def
_movietime_to_ms
(
self
,
time
):
value
,
d1
,
d2
=
Qt
.
ConvertTimeScale
((
time
,
self
.
movietimescale
,
None
),
1000
)
return
value
def
_videotime_to_ms
(
self
,
time
):
value
,
d1
,
d2
=
Qt
.
ConvertTimeScale
((
time
,
self
.
videotimescale
,
None
),
1000
)
return
value
def
_audiotime_to_ms
(
self
,
time
):
value
,
d1
,
d2
=
Qt
.
ConvertTimeScale
((
time
,
self
.
audiotimescale
,
None
),
1000
)
return
value
def
_videotime_to_movietime
(
self
,
time
):
value
,
d1
,
d2
=
Qt
.
ConvertTimeScale
((
time
,
self
.
videotimescale
,
None
),
self
.
movietimescale
)
return
value
def
HasAudio
(
self
):
return
not
self
.
audiotrack
is
None
def
HasVideo
(
self
):
return
not
self
.
videotrack
is
None
def
GetAudioDuration
(
self
):
if
not
self
.
audiotrack
:
return
0
return
self
.
_gettrackduration_ms
(
self
.
audiotrack
)
def
GetVideoDuration
(
self
):
if
not
self
.
videotrack
:
return
0
return
self
.
_gettrackduration_ms
(
self
.
videotrack
)
def
GetAudioFormat
(
self
):
bps
=
self
.
audiodescr
[
'sampleSize'
]
nch
=
self
.
audiodescr
[
'numChannels'
]
if
nch
==
1
:
channels
=
[
'mono'
]
elif
nch
==
2
:
channels
=
[
'left'
,
'right'
]
else
:
channels
=
map
(
lambda
x
:
str
(
x
+
1
),
range
(
nch
))
if
bps
%
8
:
# Funny bits-per sample. We pretend not to understand
blocksize
=
0
fpb
=
0
else
:
# QuickTime is easy (for as far as we support it): samples are always a whole
# number of bytes, so frames are nchannels*samplesize, and there's one frame per block.
blocksize
=
(
bps
/
8
)
*
nch
fpb
=
1
if
self
.
audiodescr
[
'dataFormat'
]
==
'raw '
:
encoding
=
'linear-excess'
elif
self
.
audiodescr
[
'dataFormat'
]
==
'twos'
:
encoding
=
'linear-signed'
else
:
encoding
=
'quicktime-coding-%s'
%
self
.
audiodescr
[
'dataFormat'
]
## return audio.format.AudioFormatLinear('quicktime_audio', 'QuickTime Audio Format',
## channels, encoding, blocksize=blocksize, fpb=fpb, bps=bps)
return
channels
,
encoding
,
blocksize
,
fpb
,
bps
def
GetAudioFrameRate
(
self
):
return
int
(
self
.
audiodescr
[
'sampleRate'
])
def
GetVideoFormat
(
self
):
width
=
self
.
videodescr
[
'width'
]
height
=
self
.
videodescr
[
'height'
]
return
VideoFormat
(
'dummy_format'
,
'Dummy Video Format'
,
width
,
height
,
imgformat
.
macrgb
)
def
GetVideoFrameRate
(
self
):
tv
=
self
.
videocurtime
if
tv
==
None
:
tv
=
0
flags
=
QuickTime
.
nextTimeStep
|
QuickTime
.
nextTimeEdgeOK
tv
,
dur
=
self
.
videomedia
.
GetMediaNextInterestingTime
(
flags
,
tv
,
1.0
)
dur
=
self
.
_videotime_to_ms
(
dur
)
return
int
((
1000.0
/
dur
)
+
0.5
)
def
ReadAudio
(
self
,
nframes
,
time
=
None
):
if
not
time
is
None
:
self
.
audiocurtime
=
time
flags
=
QuickTime
.
nextTimeStep
|
QuickTime
.
nextTimeEdgeOK
if
self
.
audiocurtime
==
None
:
self
.
audiocurtime
=
0
tv
=
self
.
audiomedia
.
GetMediaNextInterestingTimeOnly
(
flags
,
self
.
audiocurtime
,
1.0
)
if
tv
<
0
or
(
self
.
audiocurtime
and
tv
<
self
.
audiocurtime
):
return
self
.
_audiotime_to_ms
(
self
.
audiocurtime
),
None
h
=
Res
.
Handle
(
''
)
desc_h
=
Res
.
Handle
(
''
)
size
,
actualtime
,
sampleduration
,
desc_index
,
actualcount
,
flags
=
\
self
.
audiomedia
.
GetMediaSample
(
h
,
0
,
tv
,
desc_h
,
nframes
)
self
.
audiocurtime
=
actualtime
+
actualcount
*
sampleduration
return
self
.
_audiotime_to_ms
(
actualtime
),
h
.
data
def
ReadVideo
(
self
,
time
=
None
):
if
not
time
is
None
:
self
.
videocurtime
=
time
flags
=
QuickTime
.
nextTimeStep
if
self
.
videocurtime
==
None
:
flags
=
flags
|
QuickTime
.
nextTimeEdgeOK
self
.
videocurtime
=
0
tv
=
self
.
videomedia
.
GetMediaNextInterestingTimeOnly
(
flags
,
self
.
videocurtime
,
1.0
)
if
tv
<
0
or
(
self
.
videocurtime
and
tv
<=
self
.
videocurtime
):
return
self
.
_videotime_to_ms
(
self
.
videocurtime
),
None
self
.
videocurtime
=
tv
moviecurtime
=
self
.
_videotime_to_movietime
(
self
.
videocurtime
)
self
.
movie
.
SetMovieTimeValue
(
moviecurtime
)
self
.
movie
.
MoviesTask
(
0
)
return
self
.
_videotime_to_ms
(
self
.
videocurtime
),
self
.
_getpixmapcontent
()
def
_getpixmapcontent
(
self
):
"""Shuffle the offscreen PixMap data, because it may have funny stride values"""
rowbytes
=
Qdoffs
.
GetPixRowBytes
(
self
.
pixmap
)
width
=
self
.
videodescr
[
'width'
]
height
=
self
.
videodescr
[
'height'
]
start
=
0
rv
=
''
for
i
in
range
(
height
):
nextline
=
Qdoffs
.
GetPixMapBytes
(
self
.
pixmap
,
start
,
width
*
4
)
start
=
start
+
rowbytes
rv
=
rv
+
nextline
return
rv
def
reader
(
url
):
try
:
rdr
=
_Reader
(
url
)
except
IOError
:
return
None
return
rdr
def
_test
():
import
img
import
MacOS
Qt
.
EnterMovies
()
fss
,
ok
=
macfs
.
PromptGetFile
(
'Video to convert'
)
if
not
ok
:
sys
.
exit
(
0
)
path
=
fss
.
as_pathname
()
rdr
=
reader
(
path
)
if
not
rdr
:
sys
.
exit
(
1
)
dstfss
,
ok
=
macfs
.
StandardPutFile
(
'Name for output folder'
)
if
not
ok
:
sys
.
exit
(
0
)
dstdir
=
dstfss
.
as_pathname
()
num
=
0
os
.
mkdir
(
dstdir
)
videofmt
=
rdr
.
GetVideoFormat
()
imgfmt
=
videofmt
.
getformat
()
imgw
,
imgh
=
videofmt
.
getsize
()
timestamp
,
data
=
rdr
.
ReadVideo
()
while
data
:
fname
=
'frame%04.4d.jpg'
%
num
num
=
num
+
1
pname
=
os
.
path
.
join
(
dstdir
,
fname
)
print
'Writing'
,
fname
,
imgw
,
imgh
,
len
(
data
)
wrt
=
img
.
writer
(
imgfmt
,
pname
)
wrt
.
width
=
imgw
wrt
.
height
=
imgh
wrt
.
write
(
data
)
timestamp
,
data
=
rdr
.
ReadVideo
()
MacOS
.
SetCreatorAndType
(
pname
,
'ogle'
,
'JPEG'
)
if
num
>
20
:
print
'stopping at 20 frames so your disk does not fill up:-)'
break
print
'Total frames:'
,
num
if
__name__
==
'__main__'
:
_test
()
sys
.
exit
(
1
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment