Skip to content

Taking video screenshots from the Watcher camera

This article will be useful for you if:

  • You are arranging video surveillance at a site that does not require constant live video broadcast from streamers. For example, if you have installed video cameras to monitor a construction site, agricultural land or other slow process, it may be enough to receive screenshots from the camera(s) at user/subscriber request or at a specified frequency.
  • You are developing your own web UI or app and you want to show camera previews (thumbnails) like they are displayed in Watcher.

Flussonic Watcher API and Flussonic Media Server API allow you to implement such scenarios in your own web UI or app.

You can use MP4 screenshots that do not require additional resources since image formats are not converted to receive them. These screenshots are an exported video in mp4 format with one frame only. After taking an MP4 screenshot you can convert it to other formats, including PNG, JPG, etc., using third-party utilities such as ffmpeg. You will find an example of how to do this below on this page. There is also an example of how to put the screenshot to a web page.

Watcher prerequisites

Configure Watcher as follows to enable the screenshots feature:

  1. Setup permissions for the user on whose behalf you will request screenshots. The user must have access to the folder(s) with the required cameras. The easiest way is to create a separate Organization for such cameras and assign the corresponding user as the owner of this Organization.

    Organization and its owner

  2. Add one or several cameras from which you plan to receive screenshots to the created Organization.

Preliminary requests

Before creating the URLs for requesting screenshots, you need to make several Watcher API requests to get the necessary data:

  1. You need an authorization key to send any requests to Watcher. The x-vsaas-session or x-vsaas-api-key keys of the user configured in the previous step are suitable for the case considered in this article. For details on these keys and how to get them, see API request authorization ways.

    For example, run the http://watcher-ip/vsaas/api/v2/auth/login query to get the x-vsaas-session key.

    curl -H 'Content-Type: application/json' --data-binary '{"login":"API user", "password":"apiuser"}'

    The response will contain the session parameter which is the value of the x-vsaas-session key.

  2. After receiving the authorization key, send http://WATCHER-IP/vsaas/api/v2/cameras/.


    curl -sS -f -X GET -H 'x-vsaas-session: RYABq2AgwlgNXsqSkwSMOcX3InI'

    In response to this request, Watcher will return the parameters of cameras available to the user.

    Click here to see the example response

    In this example, two cameras were returned:

    [ { "agent_key": null, "agent_id": null, "thumbnails_url": "", "motion_detector_enabled": false, "static": true, "onvif_profile": null, "groups": [], "precise_thumbnails": false, "enabled": true, "dvr_space": null, "folder_id": 7, "precise_thumbnails_days": 0, "dvr_lock_days": 1, "agent_model": null, "user_attributes": {}, "playback_config": { "token": "2.-s9tHGUHAAEABcXhj_yu3vqQhCc5l9Zv1aS-onP8IcVoG4Pl" }, "thumbnails": false, "folder_coordinates": null, "substream_url": "", "preset": { "vision_alg": null, "vision_params": {}, "vision_areas": null, "is_adjustable": true, "vision_enabled": null, "dvr_depth": 2, "domain_id": 1, "dvr_space": null, "vision_gpu": null, "id": 8, "is_default": true, "dvr_lock_days": 1, "title": "2+1days_adjustable", "is_deleted": false }, "comment": "", "vision_alg": null, "last_change": { "object_type": "Camera", "created_at": 1623922927, "object_id": "samplecamera2-1584a116d9", "user": "admin" }, "streamer_id": 1, "onvif_ptz": false, "preset_id": 8, "dvr_path": "/dvr", "coordinates": "", "permissions": { "dvr": true, "ptz": true, "edit": true, "view": true, "actions": true }, "postal_address": "", "agent_serial": null, "dvr_depth": 2, "organization_id": 6, "video_only": false, "external_id": null, "stream_url": "file://vod/sample-10s.mp4 ", "agent_status": null, "vision_areas": null, "onvif_url": null, "vision_enabled": null, "last_event_time": null, "stream_status": { "alive": false, "lifetime": 5948, "source_error": null, "http_port": 80, "https_port": null, "bitrate": 4294, "server": "localhost" }, "name": "samplecamera2-1584a116d9", "has_actions": false, "vision_gpu": null, "title": "SampleCamera2" }, { "agent_key": null, "agent_id": null, "thumbnails_url": "", "motion_detector_enabled": false, "static": true, "onvif_profile": null, "groups": [], "precise_thumbnails": false, "enabled": true, "dvr_space": null, "folder_id": 7, "precise_thumbnails_days": 0, "dvr_lock_days": 1, "agent_model": null, "user_attributes": {}, "playback_config": { **"token": "2.-s9tHGUHAAEABcXhj_yu3gCkwPvOTwRbY3O60MZ0Qb117UHv"** }, "thumbnails": false, "folder_coordinates": null, "substream_url": "", "preset": { "vision_alg": null, "vision_params": {}, "vision_areas": null, "is_adjustable": false, "vision_enabled": null, "dvr_depth": 1, "domain_id": 1, "dvr_space": null, "vision_gpu": null, "id": 7, "is_default": true, "dvr_lock_days": 1, "title": "1+1days_non-adjustable", "is_deleted": false }, "comment": "", "vision_alg": null, "last_change": { "object_type": "Camera", "created_at": 1623923311, "object_id": "samplecamera4-fd2f695a2e", "user": "admin" }, "streamer_id": 1, "onvif_ptz": false, "preset_id": 7, "dvr_path": "/dvr", "coordinates": "", "permissions": { "dvr": true, "ptz": true, "edit": true, "view": true, "actions": true }, "postal_address": "", "agent_serial": null, "dvr_depth": 1, "organization_id": 6, "video_only": false, "external_id": null, "stream_url": "file://vod/sample-5s.mp4 ", "agent_status": null, "vision_areas": null, "onvif_url": null, "vision_enabled": null, "last_event_time": null, "stream_status": { "alive": false, "lifetime": 6008, "source_error": null, "http_port": 80, "https_port": null, "bitrate": 4081, "server": "localhost" }, "name": "samplecamera4-fd2f695a2e", "has_actions": false, "vision_gpu": null, "title": "SampleCamera4" } ]


    If you need only one camera and you know its name in the database, you may request the parameters of this camera only: http://WATCHER-IP/vsaas/api/v2/cameras/(camera_name). The response parameters are the same.

    You will need server, name and token parameters for the required camera(s).

Now you are ready to generate URLs for screenshots.

Creating the URL

Screenshot requests are addressed to the streamer directly, i.e. you use the Flussonic Media Server API to get thumbnails.

Create a separate link for requesting screenshots from each camera using the parameters obtained above.

For live stream MP4 screenshot:



You can request screenshots from the archive if DVR is enabled for the camera. Please refer to Video Thumbnails for instructions and features of URLs with time specified. Make sure to add the token parameter to the request in the same way as in the examples above.

Example request for MP4 screenshot at 29.07.2021, 14:26:24 UTC+0

If the archive was not recorded at that particular moment, Flussonic Media Server will return the closest available screenshot (within 10 minutes).

Converting MP4 screenshot to other formats using ffmpeg

First, make sure you have ffmpeg installed. Download the screenshot file in MP4 format to disk.

Example command to convert an MP4 screenshot to PNG image:

ffmpeg -i preview.mp4 preview.png

Depending on the directories in which the ffmpeg and your screenshot files are located, you may need to specify the full path to the files.

Example script to show MP4 screenshots in your browser

Below is a simple example of a JavaScript script to display MP4 screenshots from one camera in any web browser.

In the src parameter of the <video> tag, specify the live video screenshot URL created as shown above.

The screenshots will be updated at a specified frequency of 5 seconds (5000 milliseconds). If you need a different frequency, set the VIDEO_UPDATE_DELAY parameter to the required value in milliseconds.

Please also note that time must be specified in the link like this #t=1 in order for the screenshot to be displayed correctly. In the example below, this parameter is added to the link within the updateVideo () function. If something goes wrong, for example, your browser does not process this script correctly, try adding the time parameter to the link in the src parameter and removing the URL hashing from the function.

<video id="previewSource" crossorigin="anonymous" 
autoplay playsinline/></video>
  (function() {
    const VIDEO_UPDATE_DELAY = 3000;

    var previewSource = document.getElementById("previewSource");
    const videoSrc = previewSource.getAttribute('src');

    function updateVideo () {
      const nextVideoUrl = new URL(videoSrc);
      nextVideoUrl.hash = '#t=1';
      previewSource.setAttribute('src', nextVideoUrl.href);


    previewSource.addEventListener("loadeddata", function() {

      window.setTimeout(updateVideo, VIDEO_UPDATE_DELAY);

Embedding MP4 screenshots to your mobile app

Watcher provides SDKs to help you develop mobile apps for iOS or Android. Among others, the SDKs have tools for managing MP4 screenshots:

  • The FlussonicThumbnailView component to show screenshots in the Android app.
  • PreviewMp4View function to show screenshots in the iOS app.

You can find examples of how to use these tools in demo apps for iOS and Android.