A video_writer encodes frames and sound into a video file. The format
follows from the extension of the file: .mp4 and .mov
give H.264 video with AAC sound if available;
ffmpeg (Linux) also writes, e.g.,
.mkv and .webm. AVFoundation (macOS) writes
only .mp4 and
.mov. Frames are images, sdl_texture
objects (e.g., of a camera) or the image of a
frame or window:
new(W, video_writer('clip.mp4', size(640, 480), 30)),
forall(between(1, 90, I),
( draw_frame(I, Image),
send(W, append, Image) )),
send(W, close).
Frames of another size are scaled to video_writer<-size.
Encoding happens in a thread: video_writer->append
converts the frame and queues it, so it only waits if the encoder cannot
keep up. video_writer->close
encodes what is queued and finishes the file. The file is opened by the
first video_writer->append
or
video_writer->append_audio.
There are three ways to record:
<-frame_rate
until video_writer->stop.The target need not be a file. With ffmpeg (Linux) it may be a URL, which streams the video live:
rtmp://... sends FLV, e.g.,
to YouTube or Twitch;
srt://..., udp://... and tcp://...
send MPEG-TS, and
rtp://... RTP with MPEG-TS;
.m3u8 writes HLS: a playlist and
2-second segments next to it, which a web server can serve to browsers.
The target may also be code, which is executed with the writer and a
char_array holding the next encoded data. Its characters are the bytes
(0..255). The code runs in the GUI thread from the media tick, in the
order of the data. An MP4 that is not written to a file is fragmented,
so it can be played while it arrives. See video_stream_writer/4
of
library(pce_video) to write to a Prolog stream, e.g.,
the reply to an HTTP request:
new(W, video_writer(message(@prolog, send_data, @arg1),
size(640, 480), 30)),
send(W, format, mpegts),
video_writer<-live
is @on by
default for a URL. A live writer encodes with low latency and a constant video_writer<-bitrate,
and drops frames, counted in
video_writer<-dropped,
rather than making video_writer->append
wait if the encoder or the network cannot keep up.
The codecs that are available are in display<-video_encoders.
|name|code->audio.new before the first frame, open while frames
can be appended and closed after video_writer->close..g., mp4, mov, mpegts, webm, matroska,
flv or hls. @nil
selects it from the target: the extension of a file, the protocol of a
URL and fragmented mp4 for code. Set it before the first
frame.->append
drops frames rather than waiting if the encoder falls behind. @on
by default for a URL. Set it before the first frame.<-quality.
A live writer without a bitrate uses about 0.1
bit per pixel. Set it before the first frame.|window*->record.
|name|code,
size=size, frame_rate=[num], codec=[name], quality=[0..100].g., libx264)
or a codec (e.g., h264).|sdl_texture|frame|window,
at=[num]at is its time in seconds; without it, it
follows the previous frame at video_writer<-frame_rate.->append
does. The data holds samples of format (default s16)
at frequency with
channels, by default those of the sound of the video. They
are converted to the format of the video. If video_writer->audio
was not used, the first samples set the format of the sound. The sound
starts at the start of the video and has no gaps.|windowfrom at video_writer<-frame_rate
until video_writer->stop
or video_writer->close.
The frames get the time they were taken.<-recording.
Used by video_writer->record.->record.