Documentation

The goal of Ziggeo is to create a way for everyone to quickly, simply and easily adds video, audio or image capture and preview to their website. We believe we are make it possible as all you need is to copy very simple code to do so. This makes it very easy to add Ziggeo to your page even if you are not familiar with codes.

That said, we also always had a goal to provide you with many options you can use if that is what you want. This guide is created for just one such option - the custom controls.

There are 2 ways you can do this - through JavaScript or through HTML.

For fine tunning everything we would suggest using JavaScript. If you would like to use your own controls however JavaScript looks intimidating, we also have HTML approach.

For both approaches, you will need to add the header codes as well you would usually. If you are not sure what that is, you can click through and copy paste the code from this page.

Adding the controls with JavaScript will make it easier for you to do things as you would like. In this guide, we will show you how to create select box (dropdown) which will have the information about the camera and microphone shown.

We will be using our currentdevicesdetected event to provide you with the device info, however we will show you how bellow.

For that, you will need to add the following HTML code to your page:

    <div id="recorder"></div>
    <select id="select-camera"></select>
    <select id="select-mic"></select>

These are fields that we will add recorder into, and also list the cameras and microphones.

It is recommended to have the next codes either behind the window load event window.addEventListener('load', function() { or within a function of your own. The code expects that the page is loaded, or that at least the HTML codes above are available as they run.

In our case, we will make use of the window onLoad event.

First, we will want to grab reference to the fields and also create recorder.

    const mic_selection_selector = document.getElementById('select-mic');
    const camera_selection_selector = document.getElementById('select-camera');
    const recorder = new ZiggeoApi.V2.Recorder({
        element: document.getElementById("recorder"),
        attrs: {
            theme: "modern",
            themecolor: "red",
            skipinitial: true
        }
    });

    recorder.activate();

With this code we now have the reference to the field for camera as well as for the field for microphone. As we are creating recorder you have probably noticed that we also have skipinitial parameter.

This parameter is recommended to use in this setup as it makes the recorder immediately go to camera. We need to get permission for camera access in order to be able to see what cameras are available. If that was not done, the list of cameras and microphones would not be possible to collect.

Next, we will add the codes that listen to our code being accessed or not.

    recorder.on("access_granted", () => {
        if (typeof recorder.recorder !== "undefined") {
            const _recorder = recorder.recorder;
            _recorder.on("currentdevicesdetected", (currentDevices) => {
                mic_selection_selector.disabled = recorder.get("microphones").count() <= 1;
                camera_selection_selector.disabled = recorder.get("cameras").count() <= 1;

                recorder.get("cameras").iterate((cam) => {
                    const option = document.createElement('option');
                    const cam_id = cam.get("id");
                    const cam_label = cam.get("label");
                    let _details = '';
                    const cam_capabilities = cam.get("capabilities");
                    if (cam_capabilities) {
                        if (typeof cam_capabilities.width !== "undefined" &&
                            typeof cam_capabilities.height !== "undefined") {
                            _details = '(' + cam_capabilities.width.max + 'x' + 
                                        cam_capabilities.height.max + ')';
                        }
                    }
                    option.value = cam_id;
                    option.innerText = cam_label + _details;
                    option.selected = cam_id === currentDevices.video;
                    camera_selection_selector.appendChild(option);
                }, recorder);

                recorder.get("microphones").iterate((mic) => {
                    const option = document.createElement('option');
                    const cam_id = mic.get("id");
                    option.value = cam_id;
                    option.innerText = mic.get("label");
                    option.selected = cam_id === currentDevices.audio;
                    mic_selection_selector.appendChild(option);
                }, recorder);

            }, recorder);
        }
    }, recorder);

Let us see what specific parts of code do:

    mic_selection_selector.disabled = recorder.get("microphones").count() <= 1;
    camera_selection_selector.disabled = recorder.get("cameras").count() <= 1;

This part of code will help you to disable the fields in case there is 1 or less devices found. This might not be needed however if there is just 1 camera or no cameras, then you would not really have a need for changing value. Same of course if for microphone.

    const _recorder = recorder.recorder;
    _recorder.on("currentdevicesdetected", (currentDevices) => {

Here, we check if the recorder is available for us and then add listener for currentdevicesdetected event. This event will only fire once the access_granted event fires, which is why it is within the same scope.

Next we use recorder.get("cameras") to get cameras and recorder.get("microphones") to get microphones and then we iterate through them. In doing so we also create the options under each select box.

That is all you need for your own controls to be prepared. We do however have couple of more suggested actions. We will show them the same here.

    if (mic_selection_selector) {
        mic_selection_selector.addEventListener("change", (ev) => {
            const { target: { options } } = ev;
            Array.from(options).forEach(function (element) {
                if (element.selected) recorder.select_microphone(element.value);
            });
        });
    }

    if (camera_selection_selector) {
        camera_selection_selector.addEventListener("change", (ev) => {
            const { target: { options } } = ev;
            Array.from(options).forEach(function (element) {
                if (element.selected) recorder.select_camera(element.value);
            });
        });
    }

The codes above will add support for when you click on the dropdown and click to use a different camera or microphone.

Next to that, we would also suggest disabling access to controls during special events. If not, it could lead to someone trying to change the camera during recording, which is not supported and is expected to terminate the current recording.

     recorder.on("recording", () => {
        mic_selection_selector.style.display = 'none';
        camera_selection_selector.style.display = 'none';
    }, recorder);

    recorder.on("no_camera", () => {
        camera_selection_selector.disabled = true;
        // Some other actions if no camera available
    }, recorder);

    recorder.on("no_microphone", () => {
        mic_selection_selector.disabled = true;
        // Some other actions if no mics available
    }, recorder);

As you can see, if recording starts or if there is no microphone or no camera, the select boxes will be disabled.

We showed you how above, here you will find the same codes, just together as a whole, allowing you to mostly copy and paste the code to your pages.

  • The <script> element is added right behind the HTML elements, however we would not recommend that you add it in the same way to your website. It is always best to separate the scripts from HTML and include scripts into head element.
    <div id="recorder"></div>
    <select id="select-mic"></select>
    <select id="select-camera"></select>
    <script>
        window.addEventListener('load', function() {
            const micSelectionSelector = document.getElementById('select-mic');
            const cameraSelectionSelector = document.getElementById('select-camera');
            const recorder = new ZiggeoApi.V2.Recorder({
                element: document.getElementById("recorder"),
                attrs: {
                    theme: "modern",
                    themecolor: "red",
                    skipinitial: true
                }
            });

            recorder.activate();

            if (micSelectionSelector) {
                micSelectionSelector.addEventListener("change", (ev) => {
                    const { target: { options } } = ev;
                    Array.from(options).forEach(function (element) {
                        if (element.selected) recorder.select_microphone(element.value);
                    });
                });
            }

            if (cameraSelectionSelector) {
                cameraSelectionSelector.addEventListener("change", (ev) => {
                    const { target: { options } } = ev;
                    Array.from(options).forEach(function (element) {
                        if (element.selected) recorder.select_camera(element.value);
                    });
                });
            }
            
            recorder.on("access_granted", () => {
                if (typeof recorder.recorder !== "undefined") {
                    const _recorder = recorder.recorder;
                    _recorder.on("currentdevicesdetected", (currentDevices) => {
                        micSelectionSelector.disabled = recorder.get("microphones").count() <= 1;
                        cameraSelectionSelector.disabled = recorder.get("cameras").count() <= 1;

                        recorder.get("cameras").iterate((cam) => {
                            const option = document.createElement('option');
                            const cam_id = cam.get("id");
                            const cam_label = cam.get("label");
                            let _details = '';
                            const cam_capabilities = cam.get("capabilities");
                            if (cam_capabilities) {
                                if (typeof cam_capabilities.width !== "undefined" &&
                                    typeof cam_capabilities.height !== "undefined") {
                                    _details = '(' + cam_capabilities.width.max + 'x' + 
                                                cam_capabilities.height.max + ')';
                                }
                            }
                            option.value = cam_id;
                            option.innerText = cam_label + _details;
                            option.selected = cam_id === currentDevices.video;
                            cameraSelectionSelector.appendChild(option);
                        }, recorder);

                        recorder.get("microphones").iterate((mic) => {
                            const option = document.createElement('option');
                            const cam_id = mic.get("id");
                            option.value = cam_id;
                            option.innerText = mic.get("label");
                            option.selected = cam_id === currentDevices.audio;
                            micSelectionSelector.appendChild(option);
                        }, recorder);

                    }, recorder);
                }
            }, recorder);


            recorder.on("recording", () => {
                micSelectionSelector.style.display = 'none';
                cameraSelectionSelector.style.display = 'none';
            }, recorder);

            recorder.on("no_camera", () => {
                cameraSelectionSelector.disabled = true;
                // Some other actions if no camera available
            }, recorder);

            recorder.on("no_microphone", () => {
                micSelectionSelector.disabled = true;
                // Some other actions if no mics available
            }, recorder);
        });
    </script>

Unlike JavaScript approach, the HTML is great if you are already using HTML embedding and want to easily add this feature. Unlike the variations you have how to do it with JavaScript, HTML approach will offer you few pre-defined options to choose from.

Another benefit of HTML approach is that the code is much easier to understand and set up. All you would use is something like this:

    <ziggeorecorder id="recorder" 
                    ziggeo-skipinitial 
                    ziggeo-outsource-selectors="cam-cameras[disabled=false];mic-mics-radio[type='radio',className='block']"
    ></ziggeorecorder>
    <select id="cam-cameras">
        <option>Please Select Camera</option>
    </select>
    <select id="mic-mics">
      <option>Please Select Microphone</option>
    </select>

As you can see we are using skipinitial parameter just like we need for JavaScript approach. This is not important for HTML approach however the devices will not be added to the fields until we get access to camera. The only new parameter is the outsource-selectors parameter.

We do not need nor should use them within JavaScript however in HTML this parameter allows us to set things up.

We also have the select boxes under the recorder. If you wanted to show these above, then you would place them above the recorder instead.

That is it really. We need to know more to set it up in few different ways, however that is all you would need to have it running. In next section we will explain more about the different options.

Now, let us look into the outsource-selectors parameter to see what it can do for us - and how.

First, you will likely notice that the ID of the field and the value in the parameter starts with cam- and mic-. These prefixes are important. Without adding these prefixes this will not work.

So your ID could be cam-cameras or cam-example however it has to always start with cam-. Same is of course for microphones which would start with mic-.

First, the value of this parameter can be seen in 2 parts. One for cameras and another for microphones. These two are always separated by semicolon (;).

The options and their values within each part however are separated by comma (,).

These are the options:

  1. type - defaults to "select", however it can also be "radio". This would be set based on element you are using.
  2. disabled - defaults to true and will allow you to set if the control should be disabled if there is only one device or no devices.
  3. className - this is empty by default and allows you to add custom CSS class to the element, to make it easier to style.
  4. showCapabilities - if browser supports, our system will also add the capabilities option next to camera or mic. This is currently only available in Chrome. Default is true.

Sometimes it is best to see this in example, so here are few ways you could set it up:

ziggeo-outsource-selectors="cam-id[disabled=false];mic-id[type='radio']"

The code above would add the list of cameras into the 'select' field (dropdown) and will be shown and possible to change even if there is only one camera. In the same time, the microphone list will be created as radio fields and would be disabled if there is only one microphone to choose from.

ziggeo-outsource-selectors="cam-id[type='radio',disabled=true,showCapabilities=true];mic-id[type='select',className='class1 class2']"

Unlike the first example, here we are creating a list of cameras as radio options to choose from. We will also list the resolution if possible and disable the radio options if there is only 1 camera available. For microphones we will show a select box (dropdown) which will have class1 and class2 applied to each option.

If you have any questions about the same, let us know by reaching out to our support at support@ziggeo.com.