A video plays an encoded video file or stream, such as an MP4, MKV or
WebM file, with its sound. The frames go into video<-texture,
an sdl_texture, so an sdl_layer shows them in an sdl_window. The frames
keep the format of the video: the renderer of the frame converts and
scales them, so they do not go through Cairo. Graphicals displayed on
the window appear on top of the video:
new(V, video('movie.mp4')),
new(W, sdl_window('Movie', size(640, 360))),
send(W, background, black),
send(W, append, sdl_layer(V?texture)), % fit the window
send(W, open),
send(V, play).
A thread decodes the video a few frames ahead. The audio is played on the default playback device and sets the time of the video: each frame is shown when the sound of that moment plays. Without audio, or after it ended, the time comes from the system clock.
Videos are decoded by ffmpeg on Linux, AVFoundation on macOS and
Media Foundation on Windows. SWI-Prolog configured with -DXPCE_VIDEO=ffmpeg
uses ffmpeg on all platforms, which is needed for streaming (see below).
Its encoders then include those of the operating system, such as Media
Foundation and VideoToolbox, and display<-video_backend
tells which backend is used. The codecs that are available are in display<-video_decoders.
Methods that need the video, such as
video<-size
or video->play,
open it if needed.
Class video is a
source_sink: a video without a source plays the encoded data written to
it, e.g., by Prolog using pce_open/3.
This allows playing video that arrives from, e.g.,
an HTTP request, a WebSocket or a pipe:
new(V, video), pce_open(V, write, Out), set_stream(Out, type(binary)), copy_stream_data(In, Out), close(Out). % the data has ended
Formats that can be read from the start, such as MPEG-TS, WebM and fragmented MP4, play while the data arrives. If the data does not arrive in time, playing waits for it. Other formats, such as an MP4 file with its index at the end, play once the data is complete.
The source may also be a URL, e.g., https://...,
an HLS playlist (.m3u8) or rtsp://... of an IP
camera, as far as the backend supports it; ffmpeg supports all of these.
A network stream is opened in the background: video<-status
is opening and methods such as video<-size
fail until it is open, which video<-status_message
tells. video->play
while opening plays as soon as the stream is open. See video<-live
for streams that are broadcast live.
|name*closed before video->open
and after video->close, opening
while a network stream is being opened, playing while
playing, finished after the last frame and paused
otherwise.<-status
when it changes, e.g., when a network stream
is open..0..1.0 Gain
applied to the sound. Default is 1.0.->option.
|name]*<-source.
The bytes are the characters of data, which must be in the range 0..255.->append.
This allows writing to the video using pce_open/3.write.<-texture,
also if the video is paused..0..1.0 Set the
gain of the sound.|int.g., rtsp_transport tcp
for an IP camera, reconnect 1 for HTTP or rw_timeout
in microseconds.
.g., h264..g., aac.
Fails if the video has no sound we play.->position
fails and
video<-loop
is ignored. It plays from the first frame it receives. If playing falls
behind, frames and sound are dropped, so the delay stays small..g., for a thumbnail. The latter
decodes the frame without disturbing playing.