const classafParrotSdk2::VideoStreamer
sys::Obj afParrotSdk2::VideoStreamer
Utility class that attaches to the drone's onVideoFrame()
event. Example usage:
VideoStreamer.toMp4File(`droneStunts.mp4`).attachToLiveStream(drone)
Note some methods start and call out to an external FFmpeg process for video processing. Whilst this works for the limited functionality of these methods, this class is not meant to an all-encompassing FFmpeg wrapper.
For ease of use, just put ffmpeg
in the same directory as your program.
- attachToLiveStream
This attachToLiveStream(Drone drone)
Attaches this instance to the given drone and starts stream processing.
This methods sets new
onVideoFrame
andonDisconnect
hooks on the drone, but wraps any existing hooks. Meaning any hooks that were set previously, still get called.- detach
Void detach()
Reverts the
onVideoFrame
andonDisconnect
hooks to what they were beforeattachTo()
was called. Closes files and halts stream processing.- file
const File? file
The output file that the video is saved to.
Only available if this
VideoSteamer
instance was initialised via toRawFile() or toMp4File().- onDisconnectListener
const |Bool,Drone onDisconnectListener := ...
The
onDisconnect()
listener for this streamer, should you wish to attach / call it yourself- onPngImage
|Buf? onPngImage
Event hook that's called when a new PNG image becomes available.
Only available if this
VideoSteamer
instance was initialised via toPngImages().Throws
NotImmutableErr
if the function is not immutable. Note this hook is called from a different Actor / thread to the one that sets it.- onVideoFrameListener
const |Buf,PaveHeader,Drone onVideoFrameListener := ...
The
onVideoFrame()
listener for this streamer, should you wish to attach / call it yourself- pngImage
Buf? pngImage()
Returns the latest PNG image from the video stream.
Only available if this
VideoSteamer
instance was initialised via toPngImages().- toMp4File
static VideoStreamer toMp4File(Uri outputFile, [Str:Obj]? options := null)
Saves the video stream as the given MP4 file. Example:
VideoStreamer.toMp4File(`droneStunts.mp4`).attachToLiveStream(drone)
Note this method starts an external FFmpeg process and pipes the raw video frames to it. FFmpeg then wraps the video in an MP4 container and writes the file.
The input URI is given a unique numerical suffix to prevent file from being overwritten. Example,
drone.mp4
may becomedrone-001F.mp4
. See the file field to acquire the actual file created.Available options:
ffmpegPath : (Uri) the location of the FFmpeg executable. Defaults to `ffmpeg.exe` on Windows, 'ffmpeg' otherwise. ffmpegArgs : (Str[]) an array of arguments for FFmpeg. Defaults to "-f h264 -i - -f mp4 -codec:v copy -movflags +faststart".split quiet : (Bool) if true, then FFmpeg console output is suppressed. Defaults to false. actorPool : (ActorPool) the ActorPool to use for thread processing Defaults to a new instance.
If no
ffmpegPath
is given then FFmpeg is assumed to be in the current directory.- toPngImages
static VideoStreamer toPngImages([Str:Obj]? options := null)
Converts the video stream into a stream of PNG images. Example:
vs := VideoStreamer.toPngImages.attachToLiveStream(drone) vs.onPngImage = |Bug pngBuf| { echo("Got new image of size ${pngBuf.size}") }
The pngImage field always contains the latest PNG image data.
Use the onPngImage() hook to be notified of new images.
Note this method starts an external FFmpeg process and pipes the raw video frames to it. FFmpeg converts the video to PNG images and pipes it back to the
VideoStreamer
instance.Available options:
ffmpegPath : (Uri) the location of the FFmpeg executable. Defaults to `ffmpeg.exe` on Windows, 'ffmpeg' otherwise. ffmpegArgs : (Str[]) an array of arguments for FFmpeg. Defaults to "-f h264 -i - -f image2pipe -codec:v png -".split frameRate : (Int?) The frame rate FFmpeg should enforce. Defaults to null - same as video input. quiet : (Bool) if true, then FFmpeg console output is suppressed. actorPool : (ActorPool) the ActorPool to use for thread processing Defaults to a new instance.
If no
ffmpegPath
is given then FFmpeg is assumed to be in the current directory.- toRawFile
static VideoStreamer toRawFile(Uri outputFile, [Str:Obj]? options := null)
Saves raw video frames to the given file. Example:
VideoStreamer.toRawFile(`droneStunts.h264`).attachToLiveStream(drone)
Note the video consists of raw H.264 codec frames and is not readily readable by anything (with the exception of VLC, try saving the file with a
.h264
extension.)To wrap the file in a more usable
.mp4
container, try the following:C:\> ffmpeg -f h264 -i droneStunts.h264 -f mp4 -codec:v copy droneStunts.mp4
The input URI is given a unique numerical suffix to prevent file from being overwritten. Example,
drone.h264
may becomedrone-001F.h264
. See the file field to acquire the actual file created.Available options:
actorPool : (ActorPool) the ActorPool to use for thread processing Defaults to a new instance.