Video Reading
Note: Reading of audio streams is not yet implemented
Reading Video Files
VideoIO contains a simple high-level interface which allows reading of video frames from a supported video file (or from a camera device, shown later).
using VideoIO
#io = VideoIO.open(video_file)
io = VideoIO.testvideo("annie_oakley") # for testing purposes
f = VideoIO.openvideo(io)
img = read(f)
while !eof(f)
read!(f, img)
# Do something with frames
end
close(f)
Seeking through the video can be achieved via seek(f, seconds::Float64)
and seekstart(f)
to return to the start.
Base.seek
— Function.seek(s::VideoReader, seconds::AbstractFloat, seconds_min::AbstractFloat=-1.0, seconds_max::AbstractFloat=-1.0, video_stream::Integer=1, forward::Bool=false)
Seek through VideoReader object.
seek(s::VideoReader, seconds::AbstractFloat, seconds_min::AbstractFloat=-1.0, seconds_max::AbstractFloat=-1.0, video_stream::Integer=1, forward::Bool=false)
Seek through AVInput object.
Base.seekstart
— Function.seekstart(s::VideoReader, video_stream=1)
Seek to start of VideoReader object.
seekstart(avin::AVInput{T}, video_stream=1) where T <: AbstractString
Seek to start of AVInput object.
Frames can be skipped without reading frame content via skipframe(f)
and skipframes(f, n)
VideoIO.skipframe
— Function.skipframe(s::VideoReader; throwEOF=true)
Skip the next frame. If End of File is reached, EOFError thrown if throwEOF=true. Otherwise returns true if EOF reached, false otherwise.
VideoIO.skipframes
— Function.skipframes(s::VideoReader, n::Int)
Skip the next n
frames. If End of File is reached, EOFError to be thrown. With throwEOF = true
the number of frames that were skipped to be returned without error.
Total available frame count is available via counttotalframes(f)
VideoIO.counttotalframes
— Function.counttotalframes(s::VideoReader)
Count the total number of frames in the video by seeking to start, skipping through each frame, and seeking back to the start.
!!! note H264 videos encoded with crf>0
have been observed to have 4-fewer frames available for reading.
Changing the target pixel format for reading
It can be helpful to be explicit in which pixel format you wish to read frames as. Here a grayscale video is read and parsed into a Vector(Array{UInt8}}
f = VideoIO.openvideo(filename, target_format=VideoIO.AV_PIX_FMT_GRAY8)
while !eof(f)
img = reinterpret(UInt8, read(f))
end
close(f)
Video Playback
A trivial video player interface exists (no audio) through Makie.jl
. Note: Makie
must be imported first to enable playback functionality.
using Makie
using VideoIO
f = VideoIO.testvideo("annie_oakley") # downloaded if not available
VideoIO.playvideo(f) # no sound
Customization of playback can be achieved by looking at the basic expanded version of this function:
import Makie
import VideoIO
#io = VideoIO.open(video_file)
io = VideoIO.testvideo("annie_oakley") # for testing purposes
f = VideoIO.openvideo(io)
img = read(f)
scene = Makie.Scene(resolution = reverse(size(img)))
makieimg = Makie.image!(scene, img, show_axis = false, scale_plot = true)[end]
Makie.rotate!(scene, -0.5pi)
display(scene)
while !eof(f)
read!(f, img)
makieimg[1] = img
sleep(1/f.framerate)
end
This code is essentially the code in playvideo
, and will read and (without the sleep
) play a movie file as fast as possible.
Reading Camera Output
Frames can be read iteratively
using VideoIO
cam = VideoIO.opencamera()
for i in 1:100
img = read(cam)
sleep(1/cam.framerate)
end
Webcam playback
The default system webcam can be viewed directly
using Makie
using VideoIO
VideoIO.viewcam()
An expanded version of this approach:
import Makie, VideoIO
cam = VideoIO.opencamera()
img = read(cam)
scene = Makie.Scene(resolution = size(img'))
makieimg = Makie.image!(scene, img, show_axis = false, scale_plot = false)[end]
Makie.rotate!(scene, -0.5pi)
display(scene)
while isopen(scene)
read!(cam, img)
makieimg[1] = img
sleep(1/cam.framerate)
end
close(cam)
Video Properties & Metadata
VideoIO.get_start_time
— Function.get_start_time(file::String) -> DateTime
Return the starting date & time of the video file
. Note that if the starting date & time are missing, this function will return the Unix epoch (00:00 1st January 1970).
VideoIO.get_time_duration
— Function.get_time_duration(file::String) -> (DateTime, Microsecond)
Return the starting date & time as well as the duration of the video file
. Note that if the starting date & time are missing, this function will return the Unix epoch (00:00 1st January 1970).
VideoIO.get_duration
— Function.get_duration(file::String) -> Float64
Return the duration of the video file
in seconds (float).