To embed your first recorder in your website follow these 4 steps:
The Pipe recording client will detect the browser used and, depending on your environment settings, will load the appropriate video recording client.
Pipe has 2 versions of the embed code. The 1.0 version is the initial one used since launch and the 2.0 version is the new one which eliminates some of the limitations of the 1.0 embed code. The 2.0 embed code has 2 further variants: HTML and JavaScript.
This is the inital embed code used by since launch.
We now consider it rather outdated since it uses script injection, global JS vars and global functions for the JS events API. It does not support multiple recorders on the same page and its tricky to use with React, Angular or Vue.js.
Many of our clients use it but we encourage everyone to move to the 2.0 embed code as soon as it exits the beta stage.
The 2.0 embed code does not have the limitations of the 1.0 version.
2.0 HTML
The 2.0 HTML embed code in particular relies on HTML tags for easy integration with any HTML page. It will soon become the default embed code.
2.0 JS
The 2.0 Java Script embed code in particular makes it easy to use Pipe with JS heavy single page web apps like those built using React, Angular or Vue.js. You can also use it to dinamically insert, remove and control recorders in the page. It starts by loading pipe.js
so that it is loaded and ready whenever you want to add a recorder.
One of the new things you can do with our new v2.0 embed code is to add multiple recorders to the HTML page.
To do this with the v2.0 HTML embed code you must simply add multiple <piperecorder...>
tags to your HTML page, with unique IDs, one for each recorder you want on the page. You can change the attributes for each recorder to fit your needs.
Here's an example with 3 recorders of different sizes, different recording resolutions and different max recording time:
<link rel="stylesheet" href="//cdn.addpipe.com/2.0/pipe.css"/> <script type="text/javascript" src = "//cdn.addpipe.com/2.0/pipe.js"></script> <piperecorder id="tag-recorder1" pipe-width="640" pipe-height="510" pipe-qualityurl="avq/480p.xml" pipe-accounthash="ACCOUNT_HASH" pipe-eid="1" pipe-showmenu="1" pipe-mrt="60" pipe-sis="0" pipe-asv="0" pipe-mv="1" pipe-st="1" pipe-ssb="1" pipe-dpv="0" pipe-ao="0" pipe-dup="1" pipe-cornerradius="8" pipe-bgcol="0xf6f6f6" pipe-menucol="0xe9e9e9" pipe-normalcol="0x334455" pipe-overcol="0x556677" pipe-payload='{"userId":"55a95eeb936dd30100e0aff6","jobId":"55a7e6555f1bdc010014d6a1"}'></piperecorder> <piperecorder id="tag-recorder2" pipe-width="1280" pipe-height="720" pipe-qualityurl="avq/720p.xml" pipe-accounthash="ACCOUNT_HASH" pipe-eid="1" pipe-showmenu="1" pipe-mrt="120" pipe-sis="0" pipe-asv="0" pipe-mv="1" pipe-st="1" pipe-ssb="1" pipe-dpv="0" pipe-ao="0" pipe-dup="1" pipe-cornerradius="8" pipe-bgcol="0xf6f6f6" pipe-menucol="0xe9e9e9" pipe-normalcol="0x334455" pipe-overcol="0x556677" pipe-payload='{"userId":"55a95eeb936dd30100e0aff6","jobId":"55a7e6555f1bdc010014d6a1"}'></piperecorder> <piperecorder id="tag-recorder3" pipe-width="320" pipe-height="240" pipe-qualityurl="avq/240p.xml" pipe-accounthash="ACCOUNT_HASH" pipe-eid="1" pipe-showmenu="1" pipe-mrt="180" pipe-sis="0" pipe-asv="0" pipe-mv="1" pipe-st="1" pipe-ssb="1" pipe-dpv="0" pipe-ao="0" pipe-dup="1" pipe-cornerradius="8" pipe-bgcol="0xf6f6f6" pipe-menucol="0xe9e9e9" pipe-normalcol="0x334455" pipe-overcol="0x556677" pipe-payload='{"userId":"55a95eeb936dd30100e0aff6","jobId":"55a7e6555f1bdc010014d6a1"}'></piperecorder>
You can move the insertion of pipe.js
and pipe.css
to the bottom of the page (after the <piperecorder...>
tags) to avoid the page stopping from rendering until pipe.js
and pipe.css
are loaded.
After pipe.js
and the rest of the page elements load (DOMContentLoaded), pipe.js
will automatically replace the 3 tags with 3 recorders (divs with the same id) in the HTML DOM and fire PipeSDK.onRecordersInserted()
if present.
Any JS events and control API implementation that relies on PipeSDK.onRecordersInserted()
needs to be placed AFTER the code for inserting pipe.js
in the page. Otherwise you'll get a Uncaught ReferenceError: PipeSDK is not defined
error in the browser console.
To add a video recorder to the page using JavaScript just insert pipe.css
and pipe.js
in the page and use PipeSDK.insert("div-id",config-object)
every time you want to insert a recorder.
Here's for example how to insert 3 video recorders in the page. Each will replace a different DIV and have a different size (as specified in the config object).
<div id="custom-id1" ></div> <div id="custom-id2" ></div> <div id="custom-id3" ></div> <link rel="stylesheet" href="//cdn.addpipe.com/2.0/pipe.css"/> <script type="text/javascript" src = "//cdn.addpipe.com/2.0/pipe.js"></script> <script type="text/javascript"> var pipeParams1 = {size: {width:400,height:330}, qualityurl: "avq/360p.xml",accountHash:"ACCOUNT_HASH", eid:1, showMenu:"true", mrt:60,sis:0,asv:1,mv:0, dpv:0, ao:0, dup:0}; var pipeParams2 = {size: {width:640,height:430}, qualityurl: "avq/480p.xml",accountHash:"ACCOUNT_HASH", eid:1, showMenu:"true", mrt:120,sis:0,asv:1,mv:0, dpv:0, ao:0, dup:0}; var pipeParams3 = {size: {width:1280,height:750}, qualityurl: "avq/720p.xml",accountHash:"ACCOUNT_HASH", eid:1, showMenu:"true", mrt:180,sis:0,asv:1,mv:0, dpv:0, ao:0, dup:0}; PipeSDK.insert('custom-id1', pipeParams1, function(myRecorderObject){ }); PipeSDK.insert('custom-id2', pipeParams2, function(myRecorderObject){ }); PipeSDK.insert('custom-id3', pipeParams3, function(myRecorderObject){ }); </script>
You can move the insertion of pipe.js
and pipe.css
to the bottom of the page to avoid the page stopping from rendering until pipe.js
and pipe.css
are loaded but any code involving PipeSDK
will have to made after the code that inserts pipe.js
in the page.
Once a recording is made it will show up in your Pipe account area. You can see all the recordings for an environment on your account by clicking on the Recordings tab.
Here's how the list of recordings looks like:
Every recording appears on a table row along with useful information grouped in 7 columns:
ID/Date/Time/IP | the ID of the recording as it is stored in our database, the date and time when the recording was made and the IP of the device from which it was streamed or uploaded |
Source | the source (Computer or Mobile) along with the browser and OS, microphone and camera names, file name, format, original size and the payload attached to the recorder |
Transcoded | recording resolution if it is a video recording, recording duration, bitrate, converted format and converted file size |
Thumbnail | the thumbnail of the recording if (snapshot if it is a video recording or a mic icon to simbolize an audio only recording) |
Status | the status of all the processes in the pipeline (recording, transcoding, storing, etc.) |
WH | the status of each webhook active at the moment the video was inserted in our db |
Action | buttons for embedding the recording, downloading it and for pushing it to YouTube. |
Pipe officially supports the following browsers.
Important: Chrome 47+ no longer allows access to camera and microphone from insecure origins (http) with the exception of Flash. Chrome 60+ removes the exception for Flash and thus no longer allows access to camera and microphone from insecure origins (http) regardless of how one's accessing the webcam (Flash or JavaScript).
Important: only iOS 11.3+ consistently allows webcam access in web pages saved to the home screen as fullscreen apps or opened inside other apps using SFSafariViewController (source: Rick Mondello's Tweet, Stack Overflow thread).
The space occupied by the recorder client differs between the desktop recorder and mobile native recorder because the technology used is different and thus the UI is different.
The size of the desktop recorder can be changed directly from the embed code or, when generating new embed codes, from our embed panel as shown below.
In your Pipe account area, under the "Embed Recorder" tab, you will find the following panel with the width and height options:
Use the 2 inputs to specify the width and height of the black video area inside the recorder. The values are in pixels.
The height value you specify here does not include the bottom control menu which will add 30px to the height. If you set a 320x240 size for the video area and keep the bottom menu you'll end up with a 320x270 recorder in pages opened on desktop devices.
After you enter your desired size, press the "Generate Embed Code" button to update the preview and the size values in the embed code to the right of the page.
The size of the recorder won't affect the resolution & quality of the videos recorded.
If you have a recorder already embedded in your web pages or if you're in the editor and you want to do a quick change you can easily change the size of the desktop recorder.
In the 1.0 embed code the size of the recorder is specified through the size
object. You'll see this line in every 1.0 Pipe embed code:
var size = {width:400,height:330};
The height value includes the 30px bottom menu so if you want a 320x240 video area in your desktop recorder ( to avoid black bars when recording 320x240 or 4:3 video ) use 320x270 in the size
object.
In the 2.0 HTML embed code the size of the recorder is specified through the pipe-width
and pipe-height
attributes:
<piperecorder... pipe-width="400" pipe-height="330" ... >
The height value includes the 30px bottom menu so if you want a 400x300 video area in your desktop recorder ( to avoid black bars when recording at 400x300 or 4:3 video ) use 400 for the pipe-width
and 330 for the pipe-height
attributes.
In the 2.0 JS embed code the size of the recorder is specified through the width
and height
properties of the size
object:
var pipeParams = {size: {width:320,height:270}, qualityurl: "avq/360p.xml", accountHash:"1edfef4c4967d69b7129ec3ffa534002"};
The height value includes the 30px bottom menu so if you want a 320x240 video area in your desktop recorder ( to avoid black bars when recording 320x240 or 4:3 video ) use 320x270 in the size
object.
The 1.0 embed code creates 2 buttons which can be used to record and upload a video as shown in this sequence showing the demo on our homepage running in Safari on iOS (click on it for full size):
The 2 buttons are included in a div with the id hdfvr-content
. The width of this div is 100%
and the height is fixed at 120px
. Here's the div highlighted on a mobile web page with Chrome's Developer Tools
With the 2.0 embed code we've moved from using 2 buttons to only 1 button for the mobile UI. Here's the recording process from beginning to end:
Since we're only using one button the height is reduced considerably to just around 40px excluding the vertical 10px margins. The height on your website might differ depending on the font face and size CSS styles on your website which are inherited.
The width of the button adjusts to the text label inside it. If the text is too long it will wrap to the next line while remaining center aligned.
The container DIV holding the button is 100% width with a 10px top and bottom margin and it uses the pipeMobileRecorder
CSS class which you can overwrite in your CSS.
Here's the div highlighted on a mobile web page with Chrome's Developer Tools:
The button is a label element with the pipeFileInput
CSS class applied which defaults to:
1px solid #999
borderYou can overwrite the pipeFileInput
CSS class in your CSS.
Pipe's desktop recorder can be customised in terms of size (see above), colors and square/rounded corners. These styling options are available across our HTML5 and Flash recorders regardless of the embed code used (1.0 or 2.0).
You can change the colors of the desktop recorder to better fit your website design.
These can be changed from your account area for new recorders/embed codes or from the embed code directly.
Changing from the Pipe account area for new embed codes
To change the colors from you account area, you will have to open the design options panel:
From here you will be able to change from top to bottom:
Once you're done, press the "Generate Embed Code" to see the changes and get the new embed code which includes these changes.
Changing in existing embed codes
For existing embed codes that you have in your website or blog posts you can edit the code directly. Here's what you have to do depending on your embed code version and type:
Change the value of the cornerradius
, bgCol
, menuCol
,normalCol
and overCol
properties of the flashvars
object in your embed code.
var flashvars = {qualityurl: "avq/360p.xml",accountHash:"1edfef4c4967d69b7129ec3ffa534002", eid:1, showMenu:"false", mrt:120,sis:0,asv:1,mv:0, dpv:0, ao:0, dup:0, cornerradius:40, bgCol:"0xff0000", menuCol:"0xff00e3", normalCol:"0x00ff77", overCol:"0xffda00"};
Change the value of the pipe-cornerradius
, pipe-bgcol
, pipe-menucol
, pipe-normalcol
and pipe-overcol
attributes of the piperecorder
tag.
<piperecorder id="custom-id" pipe-width="400" pipe-height="300" pipe-qualityurl="avq/360p.xml" pipe-accounthash="1edfef4c4967d69b7129ec3ffa534002" pipe-eid="1" pipe-showmenu="false" pipe-mrt="120" pipe-sis="0" pipe-asv="1" pipe-mv="0" pipe-dpv="0" pipe-ao="0" pipe-dup="0" pipe-cornerradius=40 pipe-bgcol="0xff0000" pipe-menucol="0xff00e3" pipe-normalcol="0x00ff77" pipe-overcol="0xffda00" ></piperecorder>
Change the value of the cornerradius
, bgCol
, menuCol
,normalCol
and overCol
properties of your javascript config object in your embed code.
var pipeParams = {size: {width:400,height:300}, qualityurl: "avq/360p.xml",accountHash:"1edfef4c4967d69b7129ec3ffa534002", eid:1, showMenu:"false", mrt:120,sis:0,asv:1,mv:0, dpv:0, ao:0, dup:0, cornerradius:40, bgCol:"0xff0000", menuCol:"0xff00e3", normalCol:"0x00ff77", overCol:"0xffda00"};
Pipe's mobile native recorder can be customised in terms of size (see above) and colors.
Since the mobile recorder is made of 1 or 2 HTML buttons you can easily overwrite the CSS classes that apply to those elements.
When using the 1.0 embed code the user is presented with 2 buttons. As soon as the user clicks the top button the OS takes over.
Safari on iOS
Chrome on Android
When using the 2.0 embed code the user is only presented with one button. As soon as the user clicks the button the OS takes over.
For the CSS classes used by the 2.0 embed code for the recorder button shown on mobile browsers see below.
You can opt to hide the lower control menu of the desktop recorder. You may want to do this if you decide to control the recorder using the JavaScript Control API (embed code v1.0 or embed code v2.0). The menu has a height of 30px.
When generating an embed code from the Pipe account area you can hide the menu by unchecking the option shown in the image below:
Here's how the newer HTML5 recorder looks without the bottom menu:
Here's how the legacy Flash recorder looks without the bottom menu:
Recordings from the desktop recorder made on the spot using a webcam and/or microphone can be limited in length. Once the length is hit, the recorder stops the recording as if the STOP button had been clicked.
When generating a new embed code from the Pipe account area you can easily change the default length (120 seconds) by editing the Max Recording Time value and pressing the green Generate Embed Code.
The new embed code will create a recorder that will limit the length of the recordings recorded on the spot with the desktop recorder to your specified length.
The value is in seconds.
For existing embed codes that you have in your website or blog posts you can edit the code directly. Here's what you have to do depending on your embed code version and type:
Change the value of the mrt
propery of the flashvars
object in your embed code. The default value is 120 seconds.
var flashvars = {qualityurl: "avq/360p.xml",accountHash:"1edfef4c4967d69b7129ec3ffa534002", eid:1, showMenu:"true", mrt:120,sis:0,asv:1,mv:0, dpv:0, ao:0, dup:0};
Change the value of the pipe-mrt
attribute of the piperecorder
tag. The default value is 120 seconds.
<piperecorder id="custom-id" pipe-width="400" pipe-height="330" pipe-qualityurl="avq/360p.xml" pipe-accounthash="1edfef4c4967d69b7129ec3ffa534002" pipe-eid="1" pipe-showmenu="true" pipe-mrt="120" pipe-sis="0" pipe-asv="1" pipe-mv="0" pipe-dpv="0" pipe-ao="0" pipe-dup="0" ></piperecorder>
Change the value of the mrt
property of your javascript config object in your embed code. The default value is 120 seconds.
var pipeParams = {size: {width:400,height:330}, qualityurl: "avq/360p.xml",accountHash:"1edfef4c4967d69b7129ec3ffa534002", eid:1, showMenu:"true", mrt:120,sis:0,asv:1,mv:0, dpv:0, ao:0, dup:0};
When recording from mobile browsers like Safari on iOS and Chrome on Android with the mobile native recorder we can not control the length of the recorded video. The HTML Media Capture standard we're using relies on the OS capabilities to handle the video recording and it does not have an option to limit the length.
However, in Pipe, there is an option to cut mobile recordings to the max length specified in the embed code if the recording made with the mobile native recorder is longer than the maximum allowed length.
The option can be found in the Transcoding Engine section.
When relying on this mechanism you should advise your mobile users that their recordings will be cut to length.
You will only be charged for the processed portion of the recording, you will not be charged for the entire length.
By default, with the desktop recorder, users can only record a new video or audio file using their webcam and/or microphone.
You can allow users to upload an existing audio or video file they have on their desktop device by turning on the file upload feature in the embed code.
Once the feature is enabled in the embed code, the desktop recorder will show a new option to upload an existing recording:
There is currently a max size limit of 1000 MiB (1000*1024*1024 bytes). If the user tries to upload a larger file, the file will not be accepted and a message will be shown to the user.
For new embed codes you can turn on the feature from the Pipe account area. Activate the checkbox highlighted in the image below and press the green Generate Embed Code. Now copy and paste that embed code in your website.
For existing embed codes that you have in your website or blog posts you can edit the code directly. Here's what you have to do depending on your embed code version and type:
Make sure the dup
property of the flashvars
object is set to 1 like this:
If the property is missing, add it.
Make sure the pipe-dup
attribute of the piperecorder
tag is set to 1 like this:
<piperecorder id="custom-id" pipe-width="400" pipe-height="330" pipe-qualityurl="avq/360p.xml" pipe-accounthash="1edfef4c4967d69b7129ec3ffa534002" pipe-eid="1" pipe-showmenu="true" pipe-mrt="120" pipe-sis="0" pipe-asv="1" pipe-mv="0" pipe-dpv="0" pipe-ao="0" pipe-dup="1" ></piperecorder>
If the attribute is missing, add it.
Make sure the dup
property is set to 1 in your javascript config object like this:
var pipeParams = {size: {width:400,height:330}, qualityurl: "avq/360p.xml",accountHash:"1edfef4c4967d69b7129ec3ffa534002", eid:1, showMenu:"true", mrt:120, sis:0, asv:1, mv:0, dpv:0, ao:0, dup:1};
If the property is missing, add it.
Weβre currently allowing users to upload the following video & audio file types:
Video | Audio |
---|---|
mp4 mov webm 3gpp 3gpp2 flv wmv mpeg |
aac mp3 m4a mp3 wav ogg wma flac |
When audio only is turned ON (ao:1
) users will only be allowed to upload audio files.
With Pipe, the amount of control you have over the video quality depends on the recording client being used. With the new HTML5 and legacy Flash desktop recorders you have granular control over the resolution. With the mobile native recorder the resolution, audio and video quality depend on the device and the settings on the device.
Pipe has 3 desktop recorders (the HTML5 one for Chrome, Firefox and Edge (version 79+), the legacy Flash one for IE/earlier versions of Edge before version 79/Safari and the inline desktop one for Chrome on Android) but regardless of the desktop recorder used, the video quality depends hugely on 3 factors:
To control the resolution, Pipe offers 4 predefined audio/video quality profiles for the desktop recorders:
The profile you choose for your desktop recorder has a very high influence on the resolution of the videos recorded with that recorder. Not all cameras support all resolutions so some cameras will return a stream in a different resolution that the one desired. The resolutions we've selected for the profiles above are very safe though.
To use one of the predefined quality profiles (240p, 360p, 480p and 720p) just select it when generating the embed code in the Pipe account area:
The 720p (HD) video quality profile is only available with trial and PRO accounts.
If you'd like to record with a certain resolution (like for example if you want to record square videos or at higher resolutions like Full HD) you can create and use your own quality profiles. See using your own quality profiles for more information.
The recording resolution is not affected by the recorder size in the HTML page. You can have a small recorder embedded on your webpage in a sidebar that records videos at 1280x720 resolution.
The HTML5 desktop recorder will request the resolution mentioned in the quality profile. If the camera does not support it, the camera will return a stream with the closest possible resolution.
A framerate of 30fps is requested from the camera but it depends on the camera if it can supply it. Older webcams in low light situations will not be able to sustain this framerate especially with high resolutions.
Firefox compresses video data using VP8 while Chrome and Edge 79+ uses H.264. Pipe will convert the VP8 video data from Firefox to H.264 for the final .mp4 file that gets delivered to you.
Audio will be recorded as mono or stereo Opus audio at 48 kHz. It will be converted to AAC by Pipe for the final .mp4 file. Stereo audio will only be recorded from capable devices (Logitech C920, Logitech C925e, MacBook PRO with 3 mics, etc) on newer browsers (Chrome 63+ and Firefox 55+) and Edge 79+.
Firefox will apply an auto gain filter (tested with Firefox 68). Chrome will not apply any filters (tested with Chrome 76).
A noise suppression filter is turned on by default by Pipe with on Chrome, Firefox and Edge (tested on Edge 79). If you'd like to turn it off you can use the ns
parameter in the embed code as explained in working directly with the embed code.
The legacy Flash desktop recorder will request the resolution, frame rate, key frame rate, picture quality and bitrate mentioned in the quality profile. If the camera does not support the resolution, the camera will return a stream with the closest possible resolution.
You have a high control over the video compression used by Flash through the video quality profiles. You can control the frame rate (30fps by default), key frame rate (2 keyframes every second by default), picture quality (90/100 by default), and maximum bitrate (unlimited by default). For more info check out the section on using your own video quality profile.
The video will be compressed using H.264. Only mono audio can be captured and it will be compressed with Nellymoser ASAO at 44.1 kHz. The audio will be converted to AAC by Pipe for the final .mp4 file.
Chrome on Android supports only these resolutions:
So when using custom resolutions with the HTML5 desktop recorder inline in Chrome on Android devices keep in mind there is a high chance resolution requested may not be the resolution that is obtained. A resolution request of 400x300 will actually result in a 640x480 video stream.
Chrome on Android gives us VP8 video and Opus audio in .webm files. The data is converted to H.264 video and AAC audio in .mp4 files on our platform.
The audio and video quality of recordings sent through our native recorder for mobile browsers depends a lot on the OS. iOS will compress the file leading to fast upload times while Android will leave the recording unchanged resulting in high quality videos.
On iOS, a user can upload videos in 2 resolutions depending on how that video is recorded:
iOS videos will have AAC audio at 48kHz and H.264 video. The data is in a .mov container.
You can read more about the audio and video quality of recordings made with iOS from this article we've written on the topic.
Android devices on the other hand will record video at whatever resolution is set on the device and will not compress the video before uploading. This can result in long upload times but high quality videos.
The audio codec and sample rate will depend on the device itself. We've mostly seen AAC audio at 48kHz but occasionally we do get AMR audio in 3GP container and other exotic audio codecs and containers.
Non AAC audio will be converted by Pipe to AAC for the final .mp4 file.
We're seeing videos in various formats from mobile devices: mp4, mov, 3gp, webm, etc. . All these recordings are converted by Pipe to a universally working .mp4 file.
High framerate videos (60 FPS) from mobile devices will keep their FPS value after being processed by Pipe.
When uploading slow motion videos (120 FPS videos played back at 30 FPS), in some cases (iOS, Lenovo Vibe P2 with Android 7.0) the OS compresses the video down to 30 FPS while keeping the slow motion effect, in others (Huawei P20 Lite with Android 8.0) the original FPS value (120) is untouched.
Pipe allows you to use your own audio/video quality profile in the desktop recorder by linking directly to it, in the embed code, using the qualityurl
parameter. This ability comes in handy if, for example, you want to record square videos or higher resolution videos - like Full HD - with the desktop recorder.
Important: The quality profiles will only affect the desktop recorder. At the moment the resolution and video quality of recordings made on mobile using the mobile native recorder are not controlled by us but by the OS.
Here are the 4 quality profiles available through the Pipe account area: 240p, 360p, 480p and 720p. Download one, make your changes and upload it to your website.
Here's every setting you can change in the profile, which of the settings are used by each desktop recorder, and their default values:
Setting | HTML5 | HTML5 inline | legacy Flash |
---|---|---|---|
video resolution: width and height | β | β | β |
bitrate | - | - | β no limit by default |
picture quality | - | - | β 90/100 by default |
framerate | - | - | β 30fps by default |
key frames per second | - | - | β 2/s by default |
Setup the qualityurl
parameter to automatically load the .xml file through http or https depending on where Pipe is embedded. Here's an example code:
var flashvars = {qualityurl: ('https:' == document.location.protocol ? 'https://' : 'http://') +"yourdomain.com/quality_profile.xml",accountHash:"your_account_hash", eid:1, showMenu:"true", mrt:5, sis:0, asv:1};
Add the pipe-qualityurl="https://yourdomain.com/quality_profile.xml"
attribute to the piperecorder
tag.
Add the qualityurl
property to your custom javascript object like this qualityurl: ('https:' == document.location.protocol ? 'https://' : 'http://') +"yourdomain.com/quality_profile.xml"
. Your custom object will be passed as a parameter to PipeSDK.insert()
.
Important: when Pipe is embedded in a secure (https) web page it needs to load all the data (including the external video quality profile xml file) through https. When Pipe is embedded in a non secure web page (http) the video quality profile file needs to be loaded from a http location. So make sure your new video quality profile (.xml file) is hosted in a https or http location depending on where Pipe is embedded.
In order for Pipe to be able to load your custom .xml video quality profile, you will need to do the following:
<cross-domain-policy> <allow-access-from domain="*.addpipe.com"/> </cross-domain-policy>Put the code above in a text file named crossdomain.xml. It should be acessible at http://yourwebsite.com/crossdomain.xml.
Directory
, Location
, Files
or VirtualHost
sections of your server config (usually located in a *.conf file, such as httpd.conf or apache.conf), or within a .htaccess
file:
Header set Access-Control-Allow-Origin "https://SITE-WHERE-PIPE-IS-EMBEDDED.com"Also make sure you are using the same protocol depending if your site has SSL enabled or not.
Our newer 2.0 embed code uses this CSS file to control the look and feel of the HTML5 desktop recorder and mobile native recorder. Overwriting the CSS classes below will have no effect on our legacy Flash recorder which is still used on Safari, IE and Edge.
We use classes instead of ids to target HTML UI elements because the 2.0 embed code allows for multiple recorders on the same page. All the recorders on a page will have these CSS classes applied to them.
These are the most important CSS classes:
Desktop recorder classesName | Description |
---|---|
pipeRecordRTC |
is the main container for the elements in the initial screen |
pipeStartUploading |
is an utility class that hides the default UI for the HTML file upload. We recommend not to override this class |
pipeCustomUpload |
controls the look of the Upload Video / Upload Audio button together with the class pipe-upload-label |
pipeUploadAnother |
controls the look of the elements on the [Recorder or upload another one] screen |
pipeBtn |
controls how the menu buttons (Record, Play, Pause, Save) look when enabled in the recording screen |
pipeBtnOff |
controls how the menu buttons (Record, Play, Pause, Save) look when disabled in the recording screen |
pipeTimer |
controls the look of the Pipe timer when recording and in the playback screen |
pipeMicContainer pipeMicIconNoMenu pipeMeter-container pipeMeter |
these classes control the look and functionality of the microphone icon and microphone sound level displayed in the bottom right corner in the recording screen |
pipeNormal |
applies to the video container on the recording screen |
pipeMirrored |
used to mirror the video screen, we recommend to not override this class |
pipeSmallNormal |
controls how the small picture in picture video looks when playing back a video recording. We recommend to not override this class |
pipeSmallMirrored |
controls how the small picture in picture video looks when playing back a video recording, but it also mirrors it. We recommend to not override this class |
pipeMsgOverlay |
controls the look of the messages that are overlayed on the video |
pipeError |
controls the look of the error screen |
Name | Description |
---|---|
pipeMobileRecorder |
is the container for the mobile client UI elements |
pipeFileInput |
controls the look of the custom file upload button for the mobile client |
To override the classes you can simply add !important
to your own implementation of the CSS class, for example let's take the following Pipe CSS class:
.pipeRecordRTC span{ position:absolute; margin: 0; left:50%; top:50%; margin-right: -50%; transform: translate(-50%, -50%); font-family:sans-serif; font-size:18px; cursor: pointer; }
Let's say you wish to make the text in the initial record screen on the desktop recorder a little bit smaller, just 15px. To do this you simply re-declare the CSS class in your custom CSS file that you already probably have and just add the font-size:12px !important;
property:
.pipeRecordRTC span{ font-size:15px !important; }
That's it. Now the text in the initial record screen on the desktop recorder will have a smaller font size.
You can change most of the recorder client's options directly in your embed code. The size, the maximum recording time, the payload data and more can all be changed by making changes to the embed code.
To change the size of the recorder client on desktop just change the width and height values in the size
object: var size = {width:320, height:270};
. The size
object is mandatory with the 1.0 embed code.
To change any other option you need to edit or add the corresponding property of the flashvars
object. This is the list of different properties that you can add or change and what they do:
Name | Description |
accountHash (mandatory) |
The account hash value for your account, you will find it under https://addpipe.com/account. This value should not be changed. |
eid |
The ID of the environment you want the new recordings to be recorded against. It used to be a numeric value (1 for the initial Production environment and the default value) before we switched to alphanumeric environment IDs. It can be changed to any ID of an environment on your account. You can get the environment ID from the Edit environment page. |
ao |
When set to 1 , the Pipe recording client will try to record only audio. The default value is 0 . |
recorderId |
A custom string that gets sent back with every function in the desktop recorder JS Events API for the 1.0 embed code. Default value: empty string . |
Name | Description |
qualityurl (mandatory) |
The path to the audio & video quality profile. Right now, you can choose between avq/240p.xml, avq/360p.xml, avq/480p.xml and avq/720p.xml or it can be the path to your custom quality profile. |
mrt (mandatory) |
The maximum recording time in seconds for the desktop recording client. The default value is 120 . |
showMenu |
Whether or not the bottom control menu of the desktop recorder will be visible. The default value is true (visible). Change it to false to hide the bottom control menu of the desktop recording client. |
asv |
Whether or not recordings streamed through the desktop recording client should be saved & processed without user interaction. When the property/attribute is missing or it is set to 1 , the recordings will be saved automatically for further processing. When set to 0 the user will have to interact with the recorder's save button (or a custom button which triggers the save action through the JS APIs) for the new recording to be saved and processed. Default value: 1 . We delete unsaved recording files from our media servers after one hour (starting with the moment the user has disconnected or recorded a subsequent recording in the same recorder). We've created this buffer to allow the user to reconnect - in case of disconnection - and continue recording or save an unsaved recording and, less importantly, to allow for extended playback over HTTPS. |
mv |
Short for mirror video. When set to 1 , the desktop recording client will filp the video image horizontally during recording. When it is missing or set to 0 the image during recording will not be flipped. The default value is 0 . During playback the image will not be flipped. The image in the final recording will not be flipped. |
sis |
Short for skip initial screen. When set to 1 , the initial screen with the [Record Video] or [Record Audio] text will not be shown and the desktop recording client will jump directly to the webcam recording screen. The default value is 0 . |
st |
Short for show timer and goes hand in hand with the showMenu setting. When set to 0 it will hide the recording timer altogether when the recorder menu is not shown. Default value: 1 . Desktop Flash recorder only. |
ssb |
Short for show settings buttons and goes hand in hand with the showMenu setting. When set to 0 it will hide the microphone icon and microphone level meter when the bottom recorder menu is not shown. It is used in kiosk applications. Default value: 1 . |
dup |
When set to 1 , the Pipe recorder will allow users to upload pre-recorded videos or audio files. Default value: 0 . |
srec |
When set to 1 , the Pipe recorder will show the user the option to record the screen along the options to record from the camera & upload an existing recording (if the option is enabled). Default value: 0 . |
ns |
When set to 0 , the Pipe recorder will try to disable noise suppression when recording with the HTML5 desktop recorder. Default value: 1 . Desktop HTML5 recorder only. |
bgCol |
The background color of the recorder. Must be a hexadecimal value. |
cornerradius |
Controls the corner radius of the Pipe recorder. |
menuCol |
The color of the control menu of the recorder. Must be a hexadecimal value. |
normalCol |
The default color for the buttons and other clickable Pipe recorder UI elements. Must be a hexadecimal value. |
overCol |
The hover color for the buttons and other clickable Pipe recorder UI elements. Must be a hexadecimal value. |
Name | Description |
dpv |
When set to 1 , the native mobile recording client will attempt to hide the OS options that allow the user to select an existing recording from the photo/video library or from other services like iCloud Drive on iOS, Dropbox or Files on Android. The default value is 0 . Mobile native recorder client only. |
With the 2.0 HTML embed code you use the <piperecorder>
's HTML attributes to control the recording client.
All the attributes are prefixed with the pipe-
prefix, otherwise they have the same names and control the same features as with the v1 embed code. Most use the same values as v1.
This is the list of attributes you can edit or add to the <piperecorder>
HTML tag:
Name | Description |
pipe-accounthash (mandatory) |
The account hash value for your account, you will find it under https://addpipe.com/account. This value should not be changed. |
pipe-eid |
The ID of the environment you want the new recordings to be recorded against. It used to be a numeric value (1 for the initial Production environment and the default value) before we switched to alphanumeric environment IDs. It can be changed to any ID of an environment on your account. You can get the environment ID from the Edit environment page. |
pipe-ao |
When set to 1 , the Pipe recording client will try to record audio only. The default value is 0 . |
Name | Description |
pipe-qualityurl (mandatory) |
The path to the audio & video quality profile. Right now, you can choose between avq/240p.xml, avq/360p.xml, avq/480p.xml and avq/720p.xml or it can be the path to your custom quality profile. |
pipe-width (mandatory) |
the width of the recorder in pixels |
pipe-height (mandatory) |
the height of the recorder in pixels |
pipe-mrt (mandatory) |
The maximum recording time in seconds for the desktop recording client. The default value is 120 . |
pipe-showmenu |
Whether or not the bottom control menu of the desktop recorder will be visible. The default value is 1 (visible). Change the value to 0 to hide the bottom control menu. |
pipe-asv |
Whether or not recordings streamed through the desktop recording client should be saved & processed without user interaction. When the property/attribute is missing or it is set to 1 , the recordings will be saved automatically for further processing. When set to 0 the user will have to interact with the recorder's save button (or a custom button which triggers the save action through the JS APIs) for the new recording to be saved and processed. Default value: 1 . We delete unsaved recording files from our media servers after one hour (starting with the moment the user has disconnected or recorded a subsequent recording in the same recorder). We've created this buffer to allow the user to reconnect - in case of disconnection - and continue recording or save an unsaved recording and, less importantly, to allow for extended playback over HTTPS. |
pipe-mv |
Short for mirror video. When set to 1 , the desktop recording client will filp the video image horizontally during recording. When it is missing or set to 0 the image during recording will not be flipped. The default value is 0 . During playback the image will not be flipped. The image in the final recording will not be flipped. |
pipe-sis |
Short for skip initial screen. When set to 1 , the initial screen with the [Record Video] or [Record Audio] text will not be shown and the desktop recording client will jump directly to the webcam recording screen. The default value is 0 . |
pipe-st |
Short for show timer and goes hand in hand with the showMenu setting. When set to 0 will hide the recording timer altogether when the recorder menu is not shown. Default value: 1 . Desktop Flash recorder only. |
pipe-ssb |
Short for show settings buttons and goes hand in hand with the pipe-showmenu setting. When set to 0 it will hide the microphone icon and microphone level meter when the bottom recorder menu is not shown. It is used in kiosk applications. Default value: 1 . |
pipe-dup |
When set to 1 , the Pipe recorder will allow users to upload pre-recorded videos or audio files. Default value: 0 . |
pipe-srec |
When set to 1 , the Pipe recorder will show the user the option to record the screen along the options to record from the camera & upload an existing recording (if the option is enabled). Default value: 0 . |
pipe-ns |
When set to 0 , the Pipe recorder will try to disable noise suppression when recording with the HTML5 desktop recorder. Default value: 1 . Desktop HTML5 recorder only. |
pipe-bgcol |
The background color of the recorder. Must be a hexadecimal value. |
pipe-cornerradius |
Controls the corner radius of the Pipe recorder. |
pipe-menucol |
The color of the control menu of the recorder. Must be a hexadecimal value. |
pipe-normalcol |
The default color for the buttons and other clickable Pipe recorder UI elements. Must be a hexadecimal value. |
pipe-overcol |
The hover color for the buttons and other clickable Pipe recorder UI elements. Must be a hexadecimal value. |
Name | Description |
pipe-dpv |
When set to 1 , the native mobile recording client will attempt to hide the OS options that allow the user to select an existing recording from the photo/video library or from other services like iCloud Drive on iOS, Dropbox or Files on Android. The default value is 0 . Mobile native recorder client only. |
In the 2.0 JS version of the embed code you initialize your own JavaScript object (with different properties) and pass it to the PipeSDK.insert()
method
Here is a simple example:
var YOUR_CUSTOM_OBJECT_NAME = {
size: {width:640,height:390},
qualityurl: "avq/720p.xml",
accountHash:"your_account_hash",
payload:'{"userId":"55a95eeb936dd30100e0aff6","jobId":"55a7e6555f1bdc010014d6a1"}',
eid:1,
showMenu:1,
mrt:120,
sis:0,
asv:0,
mv:1,
st:1,
ssb:1,
dup:1
};
And then pass it to the function: PipeSDK.insert('ID_OF_THE_DIV_TO_BE_REPLACED', YOUR_CUSTOM_OBJECT_NAME, CALLBACK_FUNCTION);
The callback function will return the actual recorder object:
PipeSDK.insert('my_ID', parametersObject, function(recorderObject){ //custom code goes here }
See JavaScript control API and JavaScript events API section for information on how the recorderObject
can be used.
Here is the list of object properties that you can edit or add to your recorder object:
Name | Description |
accountHash (mandatory) |
The account hash value for your account, you will find it under https://addpipe.com/account. This value should not be changed. |
eid |
The ID of the environment you want the new recordings to be recorded against. It used to be a numeric value (1 for the initial Production environment and the default value) before we switched to alphanumeric environment IDs. It can be changed to any ID of an environment on your account. You can get the environment ID from the Edit environment page. |
ao |
When set to 1 , the Pipe recorder will try to record audio only. The default value is 0 . |
Name | Description |
size (mandatory) |
object that contains the width and height for the recorder, as properties |
qualityurl (mandatory) |
The path to the audio & video quality profile. Right now, you can choose between avq/240p.xml, avq/360p.xml, avq/480p.xml and avq/720p.xml or it can be the path to your custom quality profile. |
mrt (mandatory) |
The maximum recording time in seconds for the desktop recording client. The default value is 120 . |
showMenu |
Whether or not the bottom control menu of the desktop recorder will be visible. The default value is 1 (visible). Change the value to 0 to hide the control menu. |
asv |
Whether or not recordings streamed through the desktop recording client should be saved & processed without user interaction. When the property/attribute is missing or it is set to 1 , the recordings will be saved automatically for further processing. When set to 0 the user will have to interact with the recorder's save button (or a custom button which triggers the save action through the JS APIs) for the new recording to be saved and processed. Default value: 1 . We delete unsaved recording files from our media servers after one hour (starting with the moment the user has disconnected or recorded a subsequent recording in the same recorder). We've created this buffer to allow the user to reconnect - in case of disconnection - and continue recording or save an unsaved recording and, less importantly, to allow for extended playback over HTTPS. |
mv |
Short for mirror video. When set to 1 , the desktop recording client will filp the video image horizontally during recording. When it is missing or set to 0 the image during recording will not be flipped. The default value is 0 . During playback the image will not be flipped. The image in the final recording will not be flipped. |
sis |
Short for skip initial screen. When set to 1 , the initial screen with the [Record Video] or [Record Audio] text will not be shown and the desktop recording client will jump directly to the webcam recording screen. The default value is 0 . |
st |
Short for show timer and goes hand in hand with the showMenu setting. When set to 0 will hide the recording timer altogether when the recorder menu is not shown. Default value: 1 . Desktop Flash recorder only. |
ssb |
Short for show settings buttons and goes hand in hand with the showMenu setting. When set to 0 it will hide the microphone icon and microphone level meter when the bottom recorder menu is not shown. It is used in kiosk applications. Default value: 1 . |
dup |
When set to 1 , the Pipe recorder will allow users to upload pre-recorded videos or audio files. Default value: 0 . |
srec |
When set to 1 , the Pipe recorder will show the user the option to record the screen along the options to record from the camera & upload an existing recording (if the option is enabled). Default value: 0 . |
ns |
When set to 0 , the Pipe recorder will try to disable noise suppression when recording with the HTML5 desktop recorder. Default value: 1 . Desktop HTML5 recorder only. |
bgCol |
The background color of the recorder. Must be a hexadecimal value. |
cornerradius |
Controls the corner radius of the Pipe recorder. |
menuCol |
The color of the control menu of the recorder. Must be a hexadecimal value. |
normalCol |
The default color for the buttons and other clickable Pipe recorder UI elements. Must be a hexadecimal value. |
overCol |
The hover color for the buttons and other clickable Pipe recorder UI elements. Must be a hexadecimal value. |
Name | Description |
dpv |
When set to 1 , the native mobile recording client will attempt to hide the OS options that allow the user to select an existing recording from the photo/video library or from other services like iCloud Drive on iOS, Dropbox or Files on Android. The default value is: 0 . Mobile native recorder client only. |
The Pipe recording clients default to English, supports 3 other languages and can also use custom wording or a different language by using an external language file hosted by you.
The Pipe client supports the following languages: English (default), French, German and Spanish.
The Pipe desktop recorder auto-detects the preferred language setting of the browser in which it is run (using HTTP Accept Language Headers) and will use that language if available.
On mobile devices the preferred language setting in the mobile OS is used, regardless of the recording client you are using (desktop recorder on Chrome 63+ on Android or the mobile native recorder).
The Pipe desktop & mobile recording clients allow you to use your own language file (XML file hosted on your website) by linking directly to it, in the embed code, using the lang
parameter.
Step 1: create your own language file and host it
Here is one of the default language files as an example: en.xml. Download it, translate the texts and upload it to your website.
Step 2: link to the new .xml file in your Pipe embed code
Setup the lang
parameter to automatically load the .xml file through http or https depending on where Pipe is embedded. Here's an example code:
var flashvars = {qualityurl:"avq/720p.xml", lang: ('https:' == document.location.protocol ? 'https://' : 'http://') +"yourdomain.com/language_file.xml", accountHash:"your_account_hash", eid:1, showMenu:"true", mrt:5, sis:0, asv:1};
Add the pipe-lang="https://yourdomain.com/language_file.xml"
attribute to the piperecorder
tag.
Add the lang
property to your custom javascript object like so lang: ('https:' == document.location.protocol ? 'https://' : 'http://') +"yourdomain.com/language_file.xml"
. Your custom object will be passed as a parameter to PipeSDK.insert()
Important: when Pipe is embedded in a secure (https) web page it needs to load all the data (including the external language xml file) through https. When Pipe is embedded in a non secure web page (http) the language file also needs to be loaded from a http location. So make sure your new language (.xml file) is hosted in a https or http location depending on where Pipe is embedded.
Step 3: allow Pipe to load the .xml file from your website
In order for Pipe to be able to load your custom .xml language file, you will need to do the following:
<cross-domain-policy> <allow-access-from domain="*.addpipe.com"/> </cross-domain-policy>Put the code above in a text file named crossdomain.xml. It should be acessible at http://yourwebsite.com/crossdomain.xml.
Directory
, Location
, Files
or VirtualHost
sections of your server config (usually located in a *.conf file, such as httpd.conf or apache.conf), or within a .htaccess
file:Header set Access-Control-Allow-Origin "https://SITE-WHERE-PIPE-IS-EMBEDDED.com"Also make sure you are using the same protocol depending if your site has SSL enabled or not.
In the 2nd half of 2016 we've started working on our new HTML5 recording client and infrastructure. The 1st beta was released in December 2016 and it relied on WebRTC. Our 2nd generation non WebRTC video recording client was released in september 2017 and it relied on the Media Recorder API (not on WebRTC). The table below documents the most important differences between the new 2nd generation HTML5 based solution (non WebRTC) and the initial Flash based solution.
HTML5 | Flash | |
---|---|---|
Video and picture quality | Uses the resolution specified in the loaded quality profile. The maximum possible picture quality of the webcam will be used and the bitrate will directly depend on this. Since the recorded data can be higher than the available bandwidth an upload screen might appear after the recording is stopped. | Uses both the resolution and picture quality specified in the loaded quality profile. Since the recorded data can be higher than the available bandwidth an upload screen might appear after the recording is stopped. |
Buffering mechanism | Buffers the audio & video data locally allowing for high quality recordings over slow connections. | Buffers the audio & video data locally allowing for high quality recordings over slow connections. |
Initial video codecs | VP8, VP9 or H.264 | H.264 |
Initial audio codecs | Opus @ 48kHz | Nellymoser ASAO @ 44.1kHz |
Requirements | See Requirements and supported browsers. | See Requirements and supported browsers. |
Permissions needed in browser | Chrome, Firefox or Edge camera and microphone access. | Flash Player's camera and microphone access + Chrome or Firefox camera and microphone access. |
Connection process | The client directly connects through WSS to the media server over port 443/TCP. | The client directly connects through RTMPS to the media server over port 443/TCP. |
With the exception seen in the table below, the JS events API has complete parity.
Flash | HTML5 |
onFlashReady | onFlashReady |
userHasCamMic | userHasCamMic |
btRecordPressed | btRecordPressed |
btStopRecordingPressed | btStopRecordingPressed |
btPlayPressed | btPlayPressed |
btPausePressed | btPausePressed |
onUploadDone | onUploadDone |
onUploadProgress | onUploadProgress |
onCamAccess | onCamAccess |
onPlaybackComplete | onPlaybackComplete |
onRecordingStarted | onRecordingStarted |
onConnectionClosed | onConnectionClosed |
onFPSChange | onFPSChange |
onConnectionStatus | onConnectionStatus |
onMicActivityLevel | onMicActivityLevel |
onSaveOk | onSaveOk |
onRecorderReady (Embed code v1.0 only) | onRecorderReady (Embed code v1.0 only) |
onReadyToRecord (Embed code v2.0 only) | onReadyToRecord (Embed code v2.0 only) |
onRecorderInit (Embed code v1.0 only) | onRecorderInit (Embed code v1.0 only) |
The JS control API has complete parity.
Flash | HTML5 |
record | record |
stopVideo | stopVideo |
playVideo | playVideo |
pause | pause |
save | save |
getStreamTime | getStreamTime |
getPlaybackTime | getPlaybackTime |
getStreamName | getStreamName |
Our desktop recorder works by streaming data in real-time over WSS (secure websockets) to a media server hosted by us.
The HTML5 desktop recording client connects to our ingestion media servers using WSS (secured WebSockets) over port 443.
The connection is established as soon as the user presses [Record Video] or [Record Audio] or [Record Screen] on the initial screen (so earlier than with the legacy Flash recording client).
In case of a network problem resulting in disconnection, the HTML5 desktop recorder will try to reconnect 30 times before giving up.
Each of the 30 attempts to reconnect can timeout after 20 seconds. After each timeout or failed re-connection attempt, the recorder will wait between 0.5 and 5 seconds before making another attempt. Thus, it can take a maximum of 750 seconds ((20s timeout + 5s delay) * 30 attempts = 750 seconds = 12.5 minutes) for the recorder to spend all 30 attempts. This interval can be even higher if there's anything blocking the JavaScript client side.
If a disconnection happens while recording, the recording process will continue, but a message will be shown to the user. If the connection is re-established, the data recorded while the connection was interrupted will start uploading to the media server while the recording process continues.
In case of a connection problem, the HTML5 desktop recorder will show one of the following messages:
The disconnection happens AFTER a successful wss connection has been established.
Causes:
Causes:
After a disconnection, Pipe will make a total of 30 attempts to reconnect to the media server. While the attempts are made, this message is shown. This message is usually shown for a fraction of a second.
After a disconnection, when the attempt to reconnect is made through websockets. This message is shown if that websocket reconnection attempt fails. This can happen if any of the issues that caused the initial disconnect are still present.
Shown for a moment after a successful reconnect attempt.
If disconnected, after 30 unsuccessful attempts to reconnect, the connection is considered fully interrupted.
Causes:
The ingestion media servers have a recording recovery mechanism in place that recovers the recording if, while recording or uploading a recording, the connection is interrupted, and a new connection can't be established. This mechanism is triggered only if the autosave option is enabled in the embed code (by default, it is enabled).
In case of a network problem resulting in disconnection, the HTML5 desktop recorder will try to reconnect 30 times before giving up. As shown above, this process can take up to 750 seconds and even more. That's why the ingestion media server, under normal circumstances, will wait 15 minutes - from the moment the disconnection is detected server-side - before attempting to recover an unsaved recording. It needs to give the user all the time it needs to cycle through his 30 reconnect attempts.
The recovery mechanism does not function with recordings uploaded through the mobile recording client.
We recommend relying on webhooks for integrating the Pipe recording client instead of relying on the JavaScript APIs because webhooks will trigger for recovered recordings. When the disconnection is the result of the user navigating away, closing the tab, browser crash, or the window/tab being accidentally closed, the JS API events will not trigger. As a result, any POST or GET requests (made within your JS) back to your server (to save the data) will never trigger. When the disconnection results from a network connection problem like a high latency wireless connection, the JS will execute on the client, but any POST or GET requests might fail.
Pipe can record the screen on Chrome 72+, Firefox 66+ and Edge 79+ when using the HTML5 desktop recorder.
From the UI
You can easily enable screen recording from the Embed section of your dashboard:
From code
You need to add the new parameter srec
and set it to 1
in your existing embed code like so:
Add the pipe-srec="1"
attribute to the piperecorder
tag
Add the srec
property to your custom javascript object and give it a value of 1: srec:1
. Your custom object will be passed as a parameter to PipeSDK.insert()
When enabled the desktop recorder will show the [Record Screen] button:
When clicking [Record Screen], depending on the browser you are using, you will be able to record the following:
Depending on your needs, you can record the screen combined with audio from a microphone at the same time OR you can just record the screen.
On Chrome 74+ and Edge 79+ you can now record the screen together with the system sounds.
Known issues
From the UI
You can easily enable Pipe to record audio only:
From code
Alternatively you can also add the new parameter ao
and set it to 1
in your existing embed code like so:
Add the pipe-ao="1"
attribute to the piperecorder
tag
Add the ao
property to your custom javascript object and give it the value of 1: ao:1
. Your custom object will be passed as a parameter to PipeSDK.insert()
Once audio only recording is enabled the recorder will look as follows:
Desktop recorder
Mobile native recorder
On Desktop
Both the HTML 5 and Flash recorders support audio only recording.
On Mobile Android Devices
Recording just audio from Android devices is supported with both the mobile native recorder and the desktop recorder.
On Mobile iOS Devices
It is not possible to record just audio from iOS devices at this time because Safari on iOS does not support audio capture through the HTML Media Capture standard. When asked to record only audio it will give the user the (wrong) option to record a video or take a picture. The latest we've tested is iOS 12.3.1.
By looking at our (video recording) data for September 2017 we determined only 0.4% of all recordings were recorded from iOS, the rest were recorded from Android (9.6%) and from desktop devices (90%).
Desktop recorder
Mobile native recorder
When recording audio using the mobile native recorder, a wide range of containers and audio codecs will be used depending on the device and Android version. As of now the following codecs and containers are supported.
Container | Audio Codec |
---|---|
mp3 | mp3 |
m4a | aac |
3gp | amr-nb |
3gpp | amr-nb |
3gpp2 | amr-nb |
aac | aac |
All of them are converted to .mp4 files with AAC while keeping the original sampling frequency.
Transcoding can help you in many ways. Here are a few useful usecases:
It may be the case that the majority of your user base will record/upload videos using Android which is known for producing high resolution videos and not compressing them as iOS does. In this case most of the videos will have at least a full HD resolution (1920x1080).
These high resolution videos will have a large size on disk which can cause a variety of issues (slower processing, larger storage being needed etc). Setting the proper transcoding options can help you downscale the videos, making them smaller in size so that you can avoid those issue.
You can easily do this by following the steps:
In this case the setup will make sure that any video with a higher height than 720px will be downscaled to have 720px. The aspect ratio will be left unchanged unless set othewise. Videos with a lower resolution that the one that was set, won't be downscaled.
You may need your videos custom fitted for a certain type of display/player.
This can easily be achieved with a few settings:
This kind of setup will always produce videos of constant aspect ratio and resolution.
Depending on the enabled outputs in the Transcoding Engine section, the resulting files (MP4 file, original recording, snapshot and filmstrip) will be pushed to our AWS S3 buckets. Depending on the region setting for the environment you're recording with, the final recording files will be pushed to one of 3 buckets:
We use the following S3 storage classes to store the files:
For more info on Amazon S3 storage classes check out this page.
Pipe gives you to the option to not store the resulting files (raw recording, processed recording, snapshot and filmstrip) on Pipe's AWS S3 storage. This option is available independently for each environment and you can find it in the storage section.
If you activate this option, we will not push the resulting recording files to our storage. As soon as the files have been pushed to all your configured storage options ((S)FTP, S3, Dropbox) they will be deleted from our processing server.
This affects only the recordings made after the setting is turned on. Prior recordings won't be removed.
Files that fail to be pushed to your storage after up to 13 attempts across 75 hours since the recording was saved to our database are kept for 28 EEST/EET days to allow both parties to access the files and attempt a manual push.
In the case of recordings that fail to transcode after up to 13 attempts across 75 hours since the recording was saved to our database we keep the original recording for 28 EEST/EET days to allow both parties to access the file and understand why the transcoding failed (invalid recording, exotic codecs, empty recording, etc.).
The buckets we use to store recordings have CORS enabled meaning that if you send the Origin
header as part of your GET requests, the S3 bucket will reply with the actual recording together with the following headers:
Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET Access-Control-Max-Age: 3000
Here's how the request/response CORS headers look in Postman:
These CORS headers come in handy if for example you want to load a video recording in the browser and apply effects to it using Seriously.js.
Depending on the enabled outputs in the Transcoding Engine section, the resulting files (MP4 file, original recording, snapshot and filmstrip) can be pushed to any location using FTP or SFTP. You will need the hostname or IP, a user with write permissions and the password.
To set this up, just fill in the form in the "SFTP or FTP" page with the required credentials and you're good to go.
In this page you will also find the latest 100 attempts to push to the FTP account you povided.
ID | The ID of the recording that was pushed to your Amazon S3 bucket. |
Date | Date and time the push attempt was made. |
Host | The address of the server to which the recording was pushed |
Username | The username of the used account. |
Folder | The folder in which the recording was stored. |
File | The filename with the .mp4 extension. |
Status | The status returned by the server (in case of errors, you should see here). |
OK | Upload of the file was successful | |
FILE_MISSING | The local file of the recording on Pipe's storage is missing | |
UPLOAD_FAILED | This may be triggered by various causes, but mostly it is a permission problem on the remote folder, a connection interruption while uploading or a file size constraint | |
FTP_LOGIN_FAILED | Either the username or password for FTP connection are incorrect | |
INCORRECT_FTP_FOLDER | The directory or the path to the directory in which the recording should be uploaded does not exist or is incorrectly named | |
FTP_CONNECTION_TIMEOUT | The remote server timed out the FTP connection. This can happen if the remote server is behind a firewall, if does not accept remote connections or if it is offline altogether |
OK | Upload of the file was successful | |
FILE_MISSING | The local file of the recording on Pipe's storage is missing | |
UPLOAD_FAILED | This may be triggered by various causes, but mostly it is a permission problem on the remote folder, a connection interruption while uploading or a file size constraint | |
SFTP_LOGIN_FAILED | Either the username or password for SFTP connection are incorrect | |
INCORRECT_SFTP_FOLDER | The directory or the path to the directory in which the recording should be uploaded does not exist or is incorrectly named | |
SFTP_CONNECTION_TIMEOUT | The remote server timed out the SFTP connection. This can happen if the remote server is behind a firewall, if does not accept remote connections or if it is offline altogether |
The Pipe platform can push the final outputs (MP4 file, original recording, snapshot and filmstrip) to your own AWS S3 bucket for storage and delivery.
For this you'll need an AWS account, an S3 bucket and security credentials. We will cover these below.
In the end, to have Pipe push the files to your bucket, you'll have to provide the following information in the Pipe account area:
You'll also be able to configure:
Let's get started!
You can sign up for a free AWS account at https://aws.amazon.com/free/. The free account includes 5GB of storage for 12 months.
With the AWS account created you now need an S3 bucket so let's create one:
Generating the security credentials is the last part, here's what you need to do:
After the 3 steps above you should now have all the required information. You still have to provide it to Pipe, here's what you need to do:
Depending on the enabled outputs in the Transcoding Engine section, the resulting files will now be pushed to your S3 bucket.
Be advised: We are using S3 with ACL uploading, so if you are using Amazon's IAM system and you've created a custom policy for your Amazon user that is doing the upload to S3 and you are using a public Canned ACL, add the following permission/action for it: s3:PutObjectAcl
. All policies require the s3:PutObject
permission, regardless of the type of Canned ACL that you selected.
The log containing information about the latest 100 attempts to push the converted files to the S3 bucket will show the following:
Video ID | The ID of the recording that was pushed to your Amazon S3 bucket. |
Date | Date and time the push attempt was made. |
Key ID | The Key of your Amazon S3 bucket. |
Secret | The Secret Key of your Amazon S3 bucket. |
Bucket Name | The name of the Bucket to which the recording is pushed. |
Bucket Region | The region of the Bucket to which the recording is pushed. |
ACL | The Canned ACL selected for the object, in this case the recording when it is pushed. |
URL | The URL of the file on your server. |
Status | The status returned by the server (in case of errors, you should see here). |
OK | Upload of the file was successful | |
FILE_MISSING | The local file of the recording on Pipe's storage is missing | |
FAIL | This may be triggered by various Amazon S3 errors, that will be displayed in the exception column |
The resulting files (MP4 files, original recording, snapshot, filmstrip) can be pushed to your own Dropbox account for storage. For that, you'll need to create a Dropbox app and generate an access token.
The 1st thing you need is a Dropbox app so let's create one:
Important: For the time being, Dropbox does not provide a way to list or revoke specific tokens, change the permissions or expiration option associated with a token. Tokens seem to preserve the expiration option and permissions from when that token was generated. Thus anytime you change the permissions or expiration option in a Dropbox app, you must generate a new token.
After you get the acces token, go to the Dropbox tab in your Pipe account and paste it in the form.
For the Dropbox Folder, you can choose any name you wish. The recording files will be pushed to /Apps/{your app name}/{folder name}.
After you click [Save Dropbox Credentials] new recordings (and any associated files like the snapshot or filmstrip) will be pushed to your Dropbox folder.
The Dropbox storage logs (available at https://addpipe.com/dropbox_logs) will show the following:
Recording ID | The id of the recording. |
Date & time | Date and time the push attempt was made. They're in your account's timezone. |
Dropbox details | Part of the token and the folder. |
File(s) | The names (including extensions) of the files that we attempted to push. |
Status | The status returned by the Dropbox SDK (errors will be displayed here if the case). |
UPLOAD_OK | Upload of the file was successful | |
FILE_DOES_NOT_EXIST | The local files on Pipe's processing server are missing | |
FAIL | This may be triggered by various Dropbox errors. They're usually related to disk space on your Dropbox account or trying to upload to an inexistent folder | |
The given OAuth 2 access token doesn't exist or has expired | This is exactly what the error says | |
Dropbox specific error in JSON format | This is usually self explanatory and contains a lot of details. |
Webhooks allow you to create integrations which subscribe to certain events in Pipe. When one of those events is triggered, weβll send (POST) data to the webhookβs URL. Pipe allows webhook URLs up to 200 characters in length.
Webhooks can be used to receive & save the information about new recordings to your database, trigger a copy action to your own storage or execute any code.
Multiple webhooks can be set per account and with each webhook you can listen for several events.
Go to your account and click on the Webhooks tab. To add a new webhook simply click on the Add New Webhook button. You will be taken to the webhook setup page:
There are 6 events in a recording's timeline you can subscribe to with each webhook:
video_recorded
: sent as soon as a new recording is finished and saved to our database (recording is not yet converted or pushed to storage).video_converted
: sent right after a recording is converted to .mp4.video_copied_pipe_s3
: sent right after a recording is successfully stored on the Pipe (S3) storage and thus it is ready to be played back.video_copied_ftp
: sent right after a recording is successfully pushed to your (S)FTP storage.video_copied_s3
: sent right after a recording is successfully pushed to your Amazon S3 storage.video_copied_dbox
sent right after a recording is successfully pushed to Dropbox account.With every webhook event a variable named payload
will be sent (POST-ed) to the specified URL with the Content-Type
header set to application/x-www-form-urlencoded
. The value of the payload
variable will be different for each event type. Here are a few examples of what you can expect:
payload={ "version":"1.0", "event":"video_recorded", "data":{ "videoName":"STREAM_NAME", "audioCodec":"NellyMoser ASAO", "videoCodec":"H.264", "type":"flv", "id":"123", "dateTime":"2016-03-03 15:51:44", "timeZone":"Europe/Bucharest", "payload":"your payload data string", "httpReferer":"http://site_from_where_video_was_recorded.com", "cam_name":"Logitech HD Pro Webcam C920 (046d:082d)", "mic_name":"Default", "ip":"91.16.93.181", "ua":"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Mobile Safari/537.36" } }
payload={ "version":"1.0", "event":"video_converted", "data":{ "videoName":"STREAM_NAME", "duration":7, "cutToLength":0, "audioCodec":"AAC", "videoCodec":"H.264", "type":"mp4", "size":194373, "width":320, "height":240, "orientation":"landscape", "id":"0", "dateTime": "2015-10-10 16:00:36", "timeZone":"Europe/Bucharest", "payload":"your payload data string" } }
payload={ "version":"1.0", "event":"video_copied_pipe_s3", "data":{ "storedStatus":"stored successful", "videoName":"STREAM_NAME", "size":194373, "checksum_md5": "md5 file hash", "checksum_sha1": "sha1 file hash", "id":"0", "url":"https://addpipevideos.s3.amazonaws.com/b8e2f5bfd04a93b434bd8c740bff744d/STREAM_NAME.mp4", "rawRecordingUrl":"https://addpipevideos.s3.amazonaws.com/b8e2f5bfd04a93b434bd8c740bff744d/STREAM_NAME_raw.EXTENSION", "snapshotUrl":"https://addpipevideos.s3.amazonaws.com/b8e2f5bfd04a93b434bd8c740bff744d/STREAM_NAME.jpg", "filmstripUrl:"https://addpipevideos.s3.amazonaws.com/b8e2f5bfd04a93b434bd8c740bff744d/STREAM_NAME_filmstrip.jpg", "cdn":{"cdnRecordingUrl":"https://recordings-eu.addpipe.com/b8e2f5bfd04a93b434bd8c740bff744d/STREAM_NAME.mp4", "cdnRawRecordingUrl":"https://recordings-eu.addpipe.com/b8e2f5bfd04a93b434bd8c740bff744d/STREAM_NAME_raw.EXTENSION", "cdnSnapshotUrl":"https://recordings-eu.addpipe.com/b8e2f5bfd04a93b434bd8c740bff744d/STREAM_NAME.jpg", "cdnFilmstripUrl":"https://recordings-eu.addpipe.com/b8e2f5bfd04a93b434bd8c740bff744d/STREAM_NAME_filmstrip.jpg"}, "bucket":"Pipe bucket name", "region": "Pipe bucket region", "payload":"your payload data string", } }
payload={ "version":"1.0", "event":"video_copied_ftp", "data":{ "ftpUploadStatus":"upload success", "videoName":"STREAM_NAME", "type":"MP4", "size":493534, "id":"123", "payload":"your payload data string" } }
payload={ "version":"1.0", "event":"video_copied_s3", "data":{ "s3UploadStatus":"upload success", "videoName":"STREAM_NAME", "type":"MP4", "size":493534, "id":"123", "url":"https://bucketname.s3.amazonaws.com/b8e2f5bfd04a93b434bd8c740bff744d/STREAM_NAME.mp4", "rawRecordingUrl":"https://bucketname.s3.amazonaws.com/b8e2f5bfd04a93b434bd8c740bff744d/STREAM_NAME_raw.EXTENSION", "snapshotUrl":"https://bucketname.s3.amazonaws.com/b8e2f5bfd04a93b434bd8c740bff744d/STREAM_NAME.jpg", "filmstripUrl:"https://bucketname.s3.amazonaws.com/b8e2f5bfd04a93b434bd8c740bff744d/STREAM_NAME_filmstrip.jpg", "bucket":"bucketname", "region":"us-east-1", "acl":"public-read", "payload":"your payload data string" } }
payload={ "version":"1.0", "event":"video_copied_dbox", "data":{ "dboxUploadStatus":"upload success", "videoName":"STREAM_NAME", "type":"MP4", "size":493534, "id":"123", "payload":"your payload data string" } }
The data is URL encoded in transit. This means that depending on the specific function of the programming language you are using, you will either be working with the raw URL encoded data or the URL decoded data.
Some examples:
In PHP if you are using php://input
for receiving the data you will be working with the raw URL encoded data,
but if you are using $_POST["payload"]
for receiving the data, it will automatically be URL decoded.
In .NET Request.InputStream
will receive the raw URL encoded data while Request.Form["payload"]
will automatically URL decode the data.
In Ruby on Rails request.raw_post
will receive the raw URL encoded data while params["payload"]
will automatically URL decode the data
Here's an example of the video_recorded
event data being received in the two possible ways.
Raw POST data (URL encoded) | Value of payload var (URL decoded) |
payload%7B%22version%22%3A%221.0%22%2C%22event %22%3A%22video_recorded%22%2C%22data%22%3A%7B%22 videoName%22%3A%22vs1457013120534_862 %22%2C%22audioCodec%22%3A%22NellyMoser%20ASAO %22%2C%22videoCodec%22%3A%22H.264%22%2C%22 type%22%3A%22FLV%22%2C%22orientation%22%3A%22 landscape%22%2C%22id%22%3A%22123%22%2C%22d ateTime%22%3A%222016-03-03%2015%3A51%3A44%22%2C%22 timeZone%22%3A%22Europe%2FBucharest%22%2C%22 payload%22%3A%22your%20payload%20data%20string%22%2C%22 httpReferer%22%3A%22http%3A%2F%2F your_site.com%22%7D%7D |
{ "version":"1.0", "event":"video_recorded", "data":{ "videoName":"vs1457013120534_862", "audioCodec":"NellyMoser ASAO", "videoCodec":"H.264", "type":"FLV", "orientation":"landscape", "id":"123", "dateTime":"2016-03-03 15:51:44", "timeZone":"Europe/Bucharest", "payload":"your payload data string", "httpReferer":"http://your_site.com" } } |
Let's talk about the information sent by these webhooks
version
contains the current version of the Pipe's webhook API.
event
contains the name of the event that triggered this call
videoName
contains the name of the recording
duration
contains the duration in seconds with two decimals
cutToLength
contains a 1 or 0 value, indicating whether the recording was cut to length or not. This is only sent for recordings coming from mobile, desktop recorder uploads or POST API uploads.
audioCodec
contains the audio codec used in the original video (video_recorded) or in the final video (video_converted)
videoCodec
contains the video codec used in the original video (video_recorded) or in the final video (video_converted). For an audio only recording it will have the value "no_video".
type
is the original's recording file type. This can give you a clue on where this recording is coming from. For example, an iPhone will produce .mov files while the Flash desktop recorder will produce .flv files and the HTML5 recorder will produce .webm files.
size
is the size in bytes
checksum_md5
contains the 32 characters md5 hash checksum of the final recording file
checksum_sha1
contains the 40 characters md5 hash checksum of the final recording file
width
and height
represents the size of the original recording. This can also give you a clue about the device the recording is coming from. For an audio only recording they will have the value 0.
orientation
represents the orientation of the device when the recording was made. This could be either "landscape" or "portrait" or "none". For an audio only recording it will have the value "none".
id
is the ID of the recording as you will find it in your Pipe account area and as it is stored in our database.
dateTime
is the date and time relative to your set timezone at which the recording has been inserted in the db (video_recorded) or has finished converting (video_converted).
timeZone
represents your selected time zone in the account settings.
url
video_copied_pipe_s3
event, it is the full path to where the MP4 recording is located on our S3 storage. If the MP4 output is not enabled this field will be an empty string. video_copied_s3
event, it is the full path to where the MP4 recording is located on your S3 bucket. If the MP4 output is not enabled this field will be an empty string.rawRecordingUrl
video_copied_pipe_s3
event, it is the full path to where the original recording is located on our S3 storage. If the original recording output is not enabled this field will be an empty string.video_copied_s3
event, it is the full path to where the original recording is located on your S3 bucket. If the original recording output is not enabled this field will be an empty string.snapshotUrl
video_copied_pipe_s3
event, it is the full path to where the snapshot is located on our S3 storage. If the snapshot output is not enabled this will be an empty string. For an audio only recording it will have the value "audio_file".video_copied_s3
event, it is the full path to where the snapshot is located on your S3 bucket. If the snapshot output is not enabled this will be an empty string. For an audio only recording it will have the value "audio_only".filmstripUrl
video_copied_pipe_s3
event, it is the full path to where the filmstrip is located on our S3 storage. If the filmstrip output is not enabled this will be an empty string. For an audio only recording it will have the value "audio_file".video_copied_s3
event, it is the full path to where the filmstrip is located on your S3 bucket. If the filmstrip output is not enabled this will be an empty string. For an audio only recording it will have the value "audio_only".cdn
is the object containing all the CDN URLs for each of the recording outputs. Depending on the S3 origin region, the CDN links will have different specific subdomains: recordings-eu
.addpipe.com (EU) or recordings-us
.addpipe.com (US). The URLs are in sync with the S3 (origin) URLs. The CDN URLs for each output are named as follows: cdnRecordingUrl
,cdnRawRecordingUrl
,cdnSnapshotUrl
and cdnFilmstripUrl
.
payload
is the payload data in string format that can be set initially in the embed code of Pipe. Find out more at: Sending custom data using payload. If no custom payload is sent this will be an empty string.
ftpUploadStatus
is the status of the (S)FTP upload.
s3UploadStatus
is the status of the S3 upload.
bucketname
is the name of the S3 bucket.
region
is the server region of the S3 bucket.
acl
is the Amazon S3 Access Control Lists type.
dboxUploadStatus
is the status of the Dropbox upload.
httpReferer
is the link to the site from which the recording was made.
The Webhook schedule section shows the list of events we've sent data for. Events from the last 72 hours are shown for Standard accounts and from the last 30 days for PRO accounts.
If you have a webhook configured to fire for more than one event, each event will show up in this section. Events are added to this list as the recording goes through our processing pipeline.
If the first attempt of firing the webhook for an event runs into an issue/problem, you can always use this section to re-send the webhook for that particular event. You can also re-send webhooks if you just need them to be sent more than once. For each firing of a webhook, a log entry will be created in the webhook logs section.
The following information is available in the webhook schedule table:
Recording ID | The ID of the recording for which the webhook was scheduled |
Date & time | The date and time the first attempt was made |
Event type | The event that triggered the webhook |
Last HTTP status | The status of the last webhook firing |
URL | The URL of your webhook handler |
Request Headers & Request Body | The request headers and request body that were sent when the webhook was fired |
Retry | A retry button for the particular webhook |
Attempts | The number of firing attempts that were made for the particular webhook |
The Webhook logs section shows the logs associated with events from the last 72 hours (Standard accounts) or 30 days (PRO accounts). Each attempt to push data to your webhook URL for a particular event has an entry here.
For example: a recording was converted and the video_converted
webhook that you have setup has been immediately scheduled and fired but for some reason your webhook code fails to run correctly and the web server ends up responding with a 500 Internal Error HTTP status. You re-send the webhook from the schedule section. This time, the webhook fires and your webhook handling code correctly processes the data. In this example a total of 2 log entries will be created for the same webhook event, one resulted in a failiure the other one resulted in a successful execution of your code.
The following information is available in webhook logs table:
Date & time | The date and time at which the log entry was created |
Recording ID | The ID of the recording for which the webhook was fired and logged |
Connection status | The initial webhook call status. A β will be shown if everything was successful, otherwise an error code will be shown. |
SSL status | The verification status for the certificate of the server to which the webhook call is made. A β will be shown if everything was successful, otherwise an error code will be shown. |
HTTP status | The HTTP status resulted from the webhook firing |
URL | The URL of your webhook handler |
Response time | The time (in milliseconds ) it took for your webhook handler to respond to the webhook firing |
Event type | The event that triggered the webhook |
Request Headers & Request Body | The request headers and request body that were sent when the webhook was fired |
Response Headers & Response Body | The response headers and response body that were received from your webhook handler |
The table in the webhook logs section has a column named "SSL status". This is what the numeric status codes in that column (if any) mean:
0 | ok the operation was successful |
2 | unable to get issuer certificate |
3 | unable to get certificate CRL |
4 | unable to decrypt certificate's signature |
5 | unable to decrypt CRL's signature |
6 | unable to decode issuer public key |
7 | certificate signature failure |
8 | CRL signature failure |
9 | certificate is not yet valid |
10 | certificate has expired |
11 | CRL is not yet valid |
12 | CRL has expired |
13 | format error in certificate's notBefore field |
14 | format error in certificate's notAfter field |
15 | format error in CRL's lastUpdate field |
16 | format error in CRL's nextUpdate field |
17 | out of memory |
18 | self signed certificate |
19 | self signed certificate in certificate chain |
20 | unable to get local issuer certificate |
21 | unable to verify the first certificate |
22 | certificate chain too long |
23 | certificate revoked |
24 | invalid CA certificate |
25 | path length constraint exceeded |
26 | unsupported certificate purpose |
27 | certificate not trusted |
28 | certificate rejected |
29 | subject issuer mismatch |
30 | authority and subject key identifier mismatch |
31 | authority and issuer serial number mismatch |
32 | key usage does not include certificate signing |
50 | application verification failure |
Pipe automatically signs the webhook requests so you can (optionally) verify that the requests are coming from Pipe and not a third-party. This is useful if your application exposes sensitive data, but it is not required. It just adds an additional layer of protection.
Pipe adds an additional HTTP header with the webhook POST requests, X-Pipe-Signature, which contains the specific signature for the request. To verify this request, you will need to generate a signature using the same key that Pipe uses (the one in your account webhook tab) and compare the value obtained with the value sent via header.
Getting your webhook authentication key
In the webhook tab of your account, a key is automatically generated. You can use this one or reset it to generate a new one at any time. Pipe will automatically use the newest one.
Generating your own signature for comparison
In the code that receives and processes the webhook request:
Example of a PHP implementation of the steps above
/** * Generates a base64-encoded signature for a Pipe webhook request. * @param string $webhook_key the webhook's authentication key * @param string $url the webhook url * @param array $jsonData the data in JSON format received via $_POST["payload"]. */ function generateSignature($webhook_key, $url, $jsonData){ $signed_data = $url; $signed_data .= $jsonData; return base64_encode(hash_hmac('sha1', $signed_data, $webhook_key, true)); }
Handling webhook data is very simple, here's an example in PHP:
//we get the payload data from the POST $payload = $_POST["payload"]; //the data is JSON encoded, so we must decode it in an associative array $webhookData = json_decode($payload, true); //you can get the webhook type by accessing the event element in the array $type = $webhookData["event"]; //if you wish to get the name of the video you simply access it like this $vidName = $webhookData["data"]["videoName"]
Decoding the JSON data of the video_converted webhook, like in the example above, will make it easily accesible in an associative array similar to the one shown here:
Array ( [version] => 1.0 [event] => video_converted [data] => Array ( [videoName] => vsrtc1501002174_491 [duration] => 3.48 [audioCodec] => AAC [videoCodec] => H.264 [type] => MP4 [size] => 442101 [width] => 1280 [height] => 720 [orientation] => landscape [id] => 451464 [dateTime] => 2017-07-25 20:03:05 [timeZone] => Europe/Bucharest [payload] => {"userId":"55a95eeb936dd30100e0aff6","jobId":"55a7e6555f1bdc010014d6a1", "email":"asdasd@adasdae.com", "link":"https://www.amazon.com/D-G-P-4-W/dp/ref=as_li_ss_tl?ie=UTF8"} ) )
You can attach custom data to each recorder. The custom data will then be attached to all the recordings made with that recorder and it will be passed back to you through webhooks. This is very useful when you wish to tunnel data - like a user id or a submission id - from your embed code all the way to your webhook receiving code. Custom data can be a simple string or a JSON object.
The custom data will also be shown in the recordings list in the Pipe account area. In the example below, the custom payload data was "user-id:30785".
We will use flashvar
's payload
property to attach custom data to the recordings made with this recorder.
Important: the data must be in string format and the value of the payload
property must not be longer than 500 characters.
Here's how to add the payload
property to the flashvar
object. This is the default embed code:
var flashvars = {qualityurl: "avq/240p.xml",accountHash:"your_account_hash",showMenu:"true", mrt:120};
This is an embed code with the payload
property added:
var flashvars = {qualityurl: "avq/240p.xml",accountHash:"your_account_hash",showMenu:"true", mrt:120, payload:"your_payload_data_string"};
We will use the pipe-payload
attribute to attach custom data to the recordings made with this recorder.
Important: the data must be in string format and the value of the pipe-payload
attribute must not be longer than 500 characters.
Here's how to add the pipe-payload
attribute to the <piperecorder>
tag. This is the default embed code:
<piperecorder id="test-div" pipe-width="640" pipe-height="510" pipe-qualityurl="avq/480p.xml" pipe-accounthash="your_account_hash" pipe-eid="1" pipe-showmenu="1" pipe-mrt="120"></piperecorder>
This is an embed code with the pipe-payload
attribute added:
<piperecorder id="test-div" pipe-width="640" pipe-height="510" pipe-qualityurl="avq/480p.xml" pipe-accounthash="your_account_hash" pipe-eid="1" pipe-showmenu="1" pipe-mrt="120" pipe-payload="your_payload_data_string" ></piperecorder>
We will use the JavaScript object's payload
property to attach custom data to the recordings made with this recorder.
Important: the data must be in string format and the value of the payload
property must not be longer than 500 characters.
Here's how to add the payload
property to your custom JavaScript object. This is a generic JavaScript object without the payload
property:
var YOUR_CUSTOM_OBJECT_NAME = {qualityurl: "avq/240p.xml",accountHash:"your_account_hash",showMenu:1, mrt:120};
An here's the same JavaScript object but with the payload
property added:
var YOUR_CUSTOM_OBJECT_NAME = {qualityurl: "avq/240p.xml",accountHash:"your_account_hash",showMenu:1, mrt:120, payload:"your_payload_data_string"};
To send a JSON object as custom data you'll have to send it as a string through the payload
property (or pipe-payload
attribute if using the 2.0 HTML embed code).
You have two formating options in order to send the JSON correctly:
payload:'{"a":"b"}'
payload:"{\"a\":\"b\"}"
The custom data you've included in the embed code will be sent back to you with (all) the webhooks that fire for the events associated with the recordings made with that recorder. The data will be available as the value of the payload property of the data
object:
payload={
"version":"1.0",
"event":"video_converted",
"data":{
"videoName":"recording name here",
"duration":"7.56",
"audioCodec":"AAC",
"videoCodec":"H.264",
"type":"MP4",
"size":194373,
"width":320,
"height":240,
"orientation":"landscape",
"id":"123",
"dateTime": "2015-10-10 16:00:36",
"timeZone":"Europe/Bucharest",
"payload":"your_payload_data_string"
}
}
The JavaScript Control API allows you to control Pipe's desktop recorder using JavaScript.
With it you can for example create your own UI by hiding the lower menu of the desktop Pipe recorder and control the recording process through the JS Control API using your own buttons.
The 1.0 version of the embed code supports only 1 recorder on the page represented by the VideoRecorder
object. You can tell it to start recording by calling the record()
method on the VideoRecorder
object like this:
<input type="button" class="btn" value="Record" id="recordbtn" /> <script> //wait for onRecorderReady before attaching the click event to the button above function onRecorderReady(recorderId,recorderType){ document.getElementById("recordbtn").onclick = function (){ document.VideoRecorder.record(); } } </script>
Here is the full list of methods that you can call on the Pipe recorder and that make up the JS Control API:
record();
Description: This call will trigger the recorder to record a video or audio stream or to rerecord one if one is already recorded (equivalent to pressing the RECORD button).
It should be executed only after:
onCamAccess()
is called by Pipe and the value of it's 1st parameter is trueonRecorderReady()
(Embed Code v1.0) or onReadyToRecord()
(Embed Code v2.0) is called by PipeIf executed before the above 2 events the initial recording screen OR mic/cam device selection screens might be shown by Pipe in which case calling record()
will do nothing.
Return Value: none
stopVideo();
Description: This call will trigger the Pipe desktop client to stop the recording of a stream if a recording is in progress.
Return Value: none
playVideo();
Description: This call will play the recorded stream if there is one. This will not be available during or before the recording process (equivalent to pressing the PLAY button).
Return Value: none
pause();
Description: This call will pause the video recording that is currently playing. The call will not do anything if a video recording is not playing. The call is equivalent to pressing the PAUSE PLAYBACK button. Calling the function a second time will not do anything, you need to call playVideo()
to resume playback.
Return Value: none
save();
Description: If recording autosaving is disabled you can use this call to save the desired recording (equivalent to pressing the Save button). This will not be available if recording autosaving is enabled.
Return Value: none
getStreamTime();
Description: This will return the time of the played or the currently recording stream.
Return Value: a number with the current length of the recording (if called during the recording process)
getPlaybackTime();
Description: This will return the current time of the recording during playback.
Return Value: a number with the current time of the recording if called during the playback process or 0 if called outside playback
getStreamName();
Description: This call will return the stream name at any time but beware that the name of the stream might not be set at the time of the call. This is useful when you need the name of the stream during the recording.
Return Value: a string, the stream name WITHOUT the file extension. If the stream name is not set it will return an empty string.
When the Pipe HTML5 recorder is used and it's part of a modal window that the user closes (either through CSS' display: none
or by removing the modal DIV from the DOM) the webcam will continue to be acessed and it's light will continue to be turned on.
For this scenario we've built the following JS function that closes the media server connection, turns off the webcam access and clears the contents of the #hdfvr-content
DIV returning the HTML source code to its initial state:removePipeRecorder();
.
Execute it before closing the modal window. It works for both the Flash recorder and the HTML5 one.
The JavaScript Control API allows you to control Pipe's desktop recorder using JavaScript.
With it you can for example create your own UI by hiding the lower menu of the desktop Pipe recorder and control the recording process through the JS Control API using your own buttons.
When using the 2.0 HTML version of the embed code, you do not have a reference in JS to each recorder so you need to obtain one first. The way to obtain these references is by using the PipeSDK.getRecorderById()
method inside the PipeSDK.onRecordersInserted()
method. Once the reference is obtained you can execute its record()
method:
<input type="button" class="btn" value="Record" id="recordbtn" /> <script> PipeSDK.onRecordersInserted = function(){ myRecorder = PipeSDK.getRecorderById('UNIQUE_ID_OF_THE_PIPERECORDER_TAG'); myRecorder.onReadyToRecord = function(id, type){ document.getElementById("recordbtn").onclick = function (){ myRecorder.record(); } } } </script>
In the example above, after the recorder object/objects have been initialized, we get a reference (myRecorder
) to our recorder using the PipeSDK.getRecorderById()
method. After that we assign a function to the click event of a button on our page. When this button is clicked, the recording is triggered using the myRecorder.record()
method.
PipeSDK
is the root object that is automatically initialized and accessible after pipe.js
has loaded in the browser.
UNIQUE_ID_OF_THE_PIPERECORDER_TAG
is the ID of any piperecorder
tag in your page, that will automatically be replaced with a Pipe recorder. This id becomes the ID of the recorder.
All of the JavaScript Control API methods will be made available only after the onReadyToRecord()
event has been triggered.
Here is the full list of methods that you can call on the Pipe recorder and that make up the JS Control API:
record();
Description: This call will trigger the recorder to record a video or audio stream or to rerecord one if one is already recorded (equivalent to pressing the RECORD button).
It should be executed only after:
onCamAccess()
is called by Pipe and the value of it's 1st parameter is trueonRecorderReady()
(Embed Code v1.0) or onReadyToRecord()
(Embed Code v2.0) is called by PipeIf executed before the above 2 events the initial recording screen OR mic/cam device selection screens might be shown by Pipe in which case calling record()
will do nothing.
Return Value: none
stopVideo();
Description: This call will trigger the Pipe desktop client to stop the recording of a stream if a recording is in progress.
Return Value: none
playVideo();
Description: This call will play the recorded stream if there is one. This will not be available during or before the recording process (equivalent to pressing the PLAY button).
Return Value: none
pause();
Description: This call will pause the video recording that is currently playing. The call will not do anything if a video recording is not playing. The call is equivalent to pressing the PAUSE PLAYBACK button. Calling the function a second time will not do anything, you need to call playVideo()
to resume playback.
Return Value: none
save();
Description: If recording autosaving is disabled you can use this call to save the desired recording (equivalent to pressing the Save button). This will not be available if recording autosaving is enabled.
Return Value: none
getStreamTime();
Description: This will return the time of the played or the currently recording stream.
Return Value: a number with the current length of the recording (if called during the recording process)
getPlaybackTime();
Description: This will return the current time of the recording during playback.
Return Value: a number with the current time of the recording if called during the playback process or 0 if called outside playback
getStreamName();
Description: This call will return the stream name at any time but beware that the name of the stream might not be set at the time of the call. This is useful when you need the name of the stream during the recording.
Return Value: a string, the stream name WITHOUT the file extension. If the stream name is not set it will return an empty string.
remove();
Description: This call will completely remove the Pipe recorder HTML/Flash elements from the page and releases any in use resources (webcam, connection to media server) without removing the div in which it was first inserted, so the div can be reused to re-insert the recorder in the page. It works for all the Pipe clients.
Return Value: none
When using the 2.0 JavaScript version of the embed code, the recorder object is received in the callback function of the PipeSDK.insert()
method. Once the recorder object is received you can call its record()
method like this:
<input type="button" class="btn" value="Record" id="recordbtn" /> <script> PipeSDK.insert('UNIQUE_ID_OF_THE_REPLACED_DIV', paramsObject, function(myRecorderObject){ myRecorderObject.onReadyToRecord = function(id, type){ document.getElementById("recordbtn").onclick = function (){ myRecorderObject.record(); } } } </script>
In the example above, in the callback function of PipeSDK.insert()
we get our recorder object named in this case myRecorderObject
. After that we assign a function to the click event of a button on our page. When this button is clicked, the recording is triggered using myRecorderObject.record()
.
PipeSDK
is the root object that is automatically initialized and accessible after pipe.js
has loaded in the browser.
UNIQUE_ID_OF_THE_REPLACED_DIV
is the ID of any div
element in your page, that will automatically be replaced with a Pipe recorder once the PipeSDK.insert()
method is called. This id will become the ID of the recorder.
It is important to note here that the callback of PipeSDK.insert()
will be called twice when the Flash recorder is used and a normal non-skip initial screen recorder is embedded (sis:0
). The first callback needs to ensure that the remove()
function is callable for the initial screen (a DIV element in this instance) and the second callback overrides the remove()
function to be callable on the actual recorder (the OBJECT element containing the Flash SWF).
All of the JavaScript Control API methods will be made available only after the onReadyToRecord()
event has been triggered.
Here is the full list of methods that you can call on the Pipe recorder and that make up the JS Control API:
record();
Description: This call will trigger the recorder to record a video or audio stream or to rerecord one if one is already recorded (equivalent to pressing the RECORD button).
It should be executed only after:
onCamAccess()
is called by Pipe and the value of it's 1st parameter is trueonRecorderReady()
(Embed Code v1.0) or onReadyToRecord()
(Embed Code v2.0) is called by PipeIf executed before the above 2 events the initial recording screen OR mic/cam device selection screens might be shown by Pipe in which case calling record()
will do nothing.
Return Value: none
stopVideo();
Description: This call will trigger the Pipe desktop client to stop the recording of a stream if a recording is in progress.
Return Value: none
playVideo();
Description: This call will play the recorded stream if there is one. This will not be available during or before the recording process (equivalent to pressing the PLAY button).
Return Value: none
pause();
Description: This call will pause the video recording that is currently playing. The call will not do anything if a video recording is not playing. The call is equivalent to pressing the PAUSE PLAYBACK button. Calling the function a second time will not do anything, you need to call playVideo()
to resume playback.
Return Value: none
save();
Description: If recording autosaving is disabled you can use this call to save the desired recording (equivalent to pressing the Save button). This will not be available if recording autosaving is enabled.
Return Value: none
getStreamTime();
Description: This will return the time of the played or the currently recording stream.
Return Value: a number with the current length of the recording (if called during the recording process)
getPlaybackTime();
Description: This will return the current time of the recording during playback.
Return Value: a number with the current time of the recording if called during the playback process or 0 if called outside playback
getStreamName();
Description: This call will return the stream name at any time but beware that the name of the stream might not be set at the time of the call. This is useful when you need the name of the stream during the recording.
Return Value: a string, the stream name WITHOUT the file extension. If the stream name is not set it will return an empty string.
remove();
Description: This call will completely remove the Pipe recorder HTML/Flash elements from the page and releases any in use resources (webcam, connection to media server) without removing the div in which it was first inserted, so the div can be reused to re-insert the recorder in the page. It works for all the Pipe clients.
Return Value: none
Every time something happens with the desktop recorder (a button is pressed, the connection succeeds, etc.), the recorder will execute a specific JavaScript function with information about the event.
You can add these event functions to your HTML/JS app and extend them with your own code to do your bidding.
Here are some of the things you can do by extending these event functions:
When using the v1 embed code you can just add these JS event functions to your HTML page. The Pipe recorder client will detect their presence and execute them when needed.
Try adding the code below immediately after your v1 Pipe recorder embed code:
<script> function onRecorderInit(recorderId){ var args = Array.prototype.slice.call(arguments); alert("onRecorderInit("+args.join(', ')+")"); } </script>
An alert will pop up in your web page whenever the Pipe recording client finishes initializing. You can replace onRecorderInit(recorderId)
with any of the event functions below.
The desktop recorder has 2 different set of events and corresponding event functions:
This is the list of JavaScript event functions the Pipe client will execute when the user is recording from a desktop device using his webcam or microphone.
onRecorderInit(recorderId);
Description: Triggers after the initial [Record Video] or [Record Audio] screen is drawn.
Passed Parameters:
recorderId
- value of recorderId
property of flashvars
object in the embed code
Example:
function onRecorderInit(recorderId){ var args = Array.prototype.slice.call(arguments); alert("onRecorderInit("+args.join(', ')+")"); }
onRecorderReady(recorderId, recorderType);
Description: The Pipe recorder is ready to start recording videos (the interface has been built, you have allowed access to your webcam and you can see yourself in the browser)
Passed Parameters:
recorderId
- value of recorderId
property of flashvars
object in the embed code
recorderType
- a string representing the type of the recorder (flash or HTML5).
Example 1: show a browser alert when onRecorderReady
is executed
<script> function onRecorderReady(recorderId, recorderType){ var args = Array.prototype.slice.call(arguments); alert("onRecorderReady("+args.join(', ')+")"); } </script>
Example 2: wait for onRecorderReady
before allowing a HTML button to trigger the recording process
<input type="button" class="btn" value="Record" id="recordbtn" /> <script> //wait for onRecorderReady before adding the onclick event to the button above function onRecorderReady(recorderId,recorderType){ console.log("onRecorderReady executed") //when the button is clicked document.getElementById("recordbtn").onclick = function (){ //trigger the recording process ββdocument.VideoRecorder.record(); } } </script>
userHasCamMic(cam_number,mic_number, recorderId);
Description: Pipe detects the number of cams and mics a user has
Passed Parameters:
cam_number
- number of web cam drivers the user has installed on his computer
mic_number
- number of sound card and sound sources the user has installed on his computer
recorderId
- value of recorderId
property of flashvars
object in the embed code
Example:
function userHasCamMic(cam_number,mic_number, recorderId){ var args = Array.prototype.slice.call(arguments); alert("userHasCamMic("+args.join(', ')+")"); }
btRecordPressed(recorderId);
Description: RECORD button is pressed. This event does NOT mark the exact start of the recording. See onRecordingStarted
.
Passed Parameters:
recorderId
- value of recorderId
property of flashvars
object in the embed code
Example:
function btRecordPressed(recorderId){ var args = Array.prototype.slice.call(arguments); alert("btRecordPressed("+args.join(', ')+")"); }
btStopRecordingPressed(recorderId);
Description: STOP RECORD button is pressed
Passed Parameters:
recorderId
- value of recorderId
property of flashvars
object in the embed code
Example:
function btStopRecordingPressed(recorderId){ var args = Array.prototype.slice.call(arguments); alert("btStopRecordingPressed("+args.join(', ')+")"); }
btPlayPressed(recorderId);
Description: PLAY button is pressed
Passed Parameters:
recorderId
- value of recorderId
property of flashvars
object in the embed code
Example:
function btPlayPressed(recorderId){ var args = Array.prototype.slice.call(arguments); alert("btPlayPressed("+args.join(', ')+")"); }
btPausePressed(recorderId);
Description: PAUSE button is pressed
Passed Parameters:
recorderId
- value of recorderId
property of flashvars
object in the embed code
Example:
function btPausePressed(recorderId){ var args = Array.prototype.slice.call(arguments); alert("btPausePressed("+args.join(', ')+")"); }
onUploadDone(streamName, streamDuration, userId, recorderId, audioCodec, videoCodec, fileType, audioOnly, location);
Description: Recorded data finishes streaming/uploading to the media server
Passed Parameters:
streamName
- a string representing the name of the stream WITHOUT the file extension
streamDuration
- the duration of the recording/audio file in seconds but accurate to the millisecond (like this: 4.322)
userId
- the userId sent via flash vars
recorderId
- value of recorderId
property of flashvars
object in the embed code
audioCodec
- the audio codec used for the recording
videoCodec
- the video codec used for the recording
fileType
- the initial file extension for the recording: flv or webm
audioOnly
- true if it is an audio only recording, false otherwise
location
- will take one of 3 values:
location
contains the subdomain of the Amazon S3 region where the final recording and snapshot will be stored by Pipe. For the EU region, for example, the recording will be stored at https://eu1-addpipe.s3.eu-central-1.amazonaws.com/ACCOUNT_HASH/FILE_NAME.mp4. The snapshot will be at the same location but with the .jpg extension. If Do Not Store Files is turned on the final video will not be stored in this location.
Example:
function onUploadDone(streamName, streamDuration, userId, recorderId, audioCodec, videoCodec, fileType, audioOnly,location){ var args = Array.prototype.slice.call(arguments); alert("onUploadDone("+args.join(', ')+")"); }
onUploadProgress(percent);
Description: Triggers everytime upload progress is made.
Passed Parameters:
percent
- the percent at which the upload progress is at
Example:
function onUploadProgress(percent){ var args = Array.prototype.slice.call(arguments); alert("onUploadProgress("+args.join(', ')+")"); }
onCamAccess(allowed, recorderId);
Description:
onCamAccess
is triggered:
onCamAccess
being called at any time during Pipe client's lifetime. The function is triggered even if the user clicks the selected/active radio button.Flash Player's Privacy Panel when presented by the Pipe recorder client:
Internet browsers like Chrome will ask again for permission to use the webcam through a separate dialog box:
Chrome will intelligently pause Flash content to save battery life.
This applies to smaller Pipe embeds too.
When Pipe is paused by Chrome, onCamAccess
will be called, while the Pipe recorder is apparently paused, if all these 3 conditions are met:
sis:1
in the embed code)In this scenario onCamAccess
will be called, followed by onFlashReady
, while the Pipe recorder is apparently paused.
Here's how Pipe looks when it's paused by Chrome:
Use 400x300px size or bigger for Pipe embeds to prevent it from being paused by Chrome.
Passed Parameters:
allowed
is true if:
recorderId
- value of recorderId
property of flashvars
object in the embed code Example:
function onCamAccess(allowed, recorderId){ var args = Array.prototype.slice.call(arguments); alert("onCamAccess("+args.join(', ')+")"); }
onPlaybackComplete(recorderId);
Description: Pipe finishes playback of recording stream
Passed Parameters:
recorderId
- value of recorderId
property of flashvars
object in the embed code
Example:
function onPlaybackComplete(recorderId){ var args = Array.prototype.slice.call(arguments); alert("onPlaybackComplete("+args.join(', ')+")"); }
onRecordingStarted(recorderId);
Description: the Pipe desktop client started recording. This event is called ONLY if there's data to record and, when it is called, it will be called with a 200-220ms delay after the record button is pressed and the btRecordPressed
event is triggered.
Passed Parameters:
recorderId
- value of recorderId
property of flashvars
object in the embed code
Example:
function onRecordingStarted(recorderId){ var args = Array.prototype.slice.call(arguments); alert("onRecordingStarted("+args.join(', ')+")"); }
onConnectionClosed(recorderId);
Description: the connection to the media server has failed completely (the connection could not be reestablished even after the 30 reconnection attempts in the HTML5 recorder)
Passed Parameters:
recorderId
- value of recorderId
property of flashvars
object in the embed code
Example:
function onConnectionClosed(recorderId){ var args = Array.prototype.slice.call(arguments); alert("onConnectionClosed("+args.join(', ')+")"); }
onFPSChange(recorderId,currentFPS);
Important: this function is not triggered by the HTML 5 recorder, only by the Flash one.
Description: called by the Pipe desktop Flash client every second with the current FPS value
Passed Parameters:
recorderId
- value of recorderId
property of flashvars
object in the embed code
currentFPS
- the current frames-per-second that the Pipe desktop client reports (during recording, playback, uploading or saving) depending of the state of the Pipe desktop client
Example:
function onFPSChange(recorderId,currentFPS){ var args = Array.prototype.slice.call(arguments); alert("onFPSChange("+args.join(', ')+")"); }
onConnectionStatus(status, recorderId);
Description: Called by the Pipe desktop client for every connection event
Passed Parameters:
status
- the actual connection status:
Flash only
HTML5 only
recorderId
- value of recorderId
property of flashvars
object in the embed code
Example:
function onConnectionStatus(status, recorderId){ var args = Array.prototype.slice.call(arguments); alert("onConnectionStatus("+args.join(', ')+")"); }
onMicActivityLevel(recorderId, currentActivityLevel);
Description: the function is called by the Pipe desktop client every 10th of a second (100 milliseconds) with the current microphone level.
Passed Parameters:
recorderId
- value of recorderId
property of flashvars
object in the embed code
currentActivityLevel
- The amount of sound the microphone is detecting in numeric values between 0 and 100. From our experience it's hard to get values over 50 though.
Example:
function onMicActivityLevel(recorderId, currentActivityLevel){ var args = Array.prototype.slice.call(arguments); alert("onMicActivityLevel("+args.join(', ')+")"); }
onSaveOk(streamName, streamDuration, userId, cameraName, micName, recorderId, audioCodec, videoCodec, fileType, videoId, audioOnly, location);
Description: The recording data has been fully streamed to our media servers for further processing.
This is not a confirmation that the recorded file is ready for delivery as the recording will take a few seconds to be processed (conversion to .mp4, snapshot extraction, rotation, push to storage location).
Use Pipe's webhooks to be notified when the recording is fully processed and ready for delivery.
Passed Parameters:
streamName
- a string representing the name of the stream WITHOUT the file extension
streamDuration
- the duration of the recorded video/audio file in seconds but accurate to the millisecond (like this: 4.322)
userId
- variable sent via flash vars
cameraName
- the name of the webcam driver the user has selected for capturing video data
micName
- the name of the sound card/mic driver the user has selected for capturing audio data
recorderId
- value of recorderId
property of flashvars
object in the embed code
audioCodec
- the audio codec used for the recording
videoCodec
- the video codec used for the recording
fileType
- the initial file extension for the recording: flv or webm
videoId
- a string representing the recording id in Pipe's database (same recording id that is sent through the webhook)
audioOnly
- true if it is an audio only recording, false otherwise
location
- will take one of 3 values:
location
contains the subdomain of the Amazon S3 region where the final recording and snapshot will be stored by Pipe. For the EU region, for example, the recording will be stored at https://eu1-addpipe.s3.eu-central-1.amazonaws.com/ACCOUNT_HASH/FILE_NAME.mp4. The snapshot will be at the same location but with the .jpg extension. If Do Not Store Files is turned on the final video will not be stored in this location.
Example:
function onSaveOk(streamName, streamDuration, userId, cameraName, micName, recorderId, audioCodec, videoCodec, fileType, videoId, audioOnly,location){ var args = Array.prototype.slice.call(arguments); alert("onSaveOk("+args.join(', ')+")"); }
onFlashReady(recorderId);
Important: this function is deprecated
Description: onFlashReady(recorderId);
is called when the recording UI has been built (after clicking "Record Video or Record Audio" on both the initial screen and on the camera/mic selection screen which shows up if you have more than 1 cam/mic) and Flash is ready to accept calls to the JS Control API v1.0 from HTML/JS
Chrome will intelligently pause Flash content to save battery life.
This applies to smaller Pipe embeds too.
When Pipe is paused by Chrome, onFlashReady
will be called, while the Pipe recorder is apparently paused, if these 2 conditions are met:
sis:1
in the embed code)In this scenario onFlashReady
will be called while the Pipe recorder is apparently paused.
If the user has also previously checked [ ] Remember in FP's Privacy panel onCamAccess
will be called, followed by onFlashReady
, while the Pipe recorder is apparently paused.
Here's how Pipe looks when it's paused by Chrome:
Use 400x300px size or bigger for Pipe embeds to prevent it from being paused by Chrome.
Passed Parameters:
recorderId
- value of recorderId
property of flashvars
object in the embed code
Example:
function onFlashReady(recorderId){ var args = Array.prototype.slice.call(arguments); alert("onFlashReady("+args.join(', ')+")"); }
Below is the list of JavaScript functions the Pipe client will execute when the user is UPLOADING an existing video using the desktop recorder. You can turn on the feature from your embed code or from the Pipe account area when generating an embed code, details here.
onDesktopVideoSelected(filename, filetype, audioOnly);
Description: The user has selected a recording from the computer's library and the recording is ready for upload.
Passed Parameters:
filename
- the (automatically generated) name of the recording without extension
filetype
- the file extension of the uploaded video, it can be mp4, mov, 3gp, m4v, mkv, avi, mp3, wma etc.
audioOnly
- true if we're expecting an audio only recording, false otherwise
Example:
function onDesktopVideoSelected(filename,filetype, audioOnly){ var args = Array.prototype.slice.call(arguments); alert("onDesktopVideoSelected("+args.join(', ')+")"); }
onDesktopVideoSubmitted();
Description: Triggered when the recording is auto-submitted.
Passed Parameters: None
Example:
function onDesktopVideoSubmitted(){ var args = Array.prototype.slice.call(arguments); alert("onDesktopVideoSubmitted("+args.join(', ')+")"); }
onDesktopVideoUploadSuccess(filename, filetype, videoId, audioOnly, location);
Description: The recording has finished uploading successfully.
Passed Parameters:
filename
- the automatically generated name of the recording
filetype
- the file extension of the uploaded video, it can be mp4, mov, 3gp, m4v, mkv, avi, mp3, wma etc.
videoId
- a string representing the recording id in Pipe's database (same recording id that is sent through the webhook)
audioOnly
- true if it is an audio only recording, false otherwise
location
- will take one of 3 values:
location
contains the subdomain of the Amazon S3 region where the final recording and snapshot will be stored by Pipe. For the EU region, for example, the recording will be stored at https://eu1-addpipe.s3.eu-central-1.amazonaws.com/ACCOUNT_HASH/FILE_NAME.mp4. The snapshot will be at the same location but with the .jpg extension. If Do Not Store Files is turned on the final video will not be stored in this location.
Example:
function onDesktopVideoUploadSuccess(filename,filetype,videoId,audioOnly,location){ var args = Array.prototype.slice.call(arguments); alert("onDesktopVideoUploadSuccess("+args.join(', ')+")"); }
onDesktopVideoUploadProgress(percent);
Description: Triggers everytime upload progress is made.
Passed Parameters:
percent
- the percent at which the upload progress is at
Example:
function onDesktopVideoUploadProgress(percent){ var args = Array.prototype.slice.call(arguments); alert("onDesktopVideoUploadProgress("+args.join(', ')+")"); }
onDesktopVideoUploadFailed(error);
Description: There was an error while uploading the recording.
Passed Parameters:
error
- The error thrown when the upload failed to complete
Example:
function onDesktopVideoUploadFailed(error){ var args = Array.prototype.slice.call(arguments); alert("onDesktopVideoUploadFailed("+args.join(', ')+")"); }
Every time something happens with the desktop recorder (a button is pressed, the connection succeeds, etc.), the recorder will execute a specific JavaScript function with information about the event.
You can add these event functions to your HTML/JS app and extend them with your own code to do your bidding.
Here are some of the things you can do by extending these event functions:
Since the v2 embed code supports multiple recorders on the same page, to override a recoder's event functions, we need to get the desired recorder object 1st. Here's how to do it:
This is done differently depending on what version of the embed code you are using.
When using the v2.0 HTML embed code you can use the PipeSDK.getRecorderById()
method to get a reference to a recorder object.
For example:
var myRecorderObject = PipeSDK.getRecorderById('UNIQUE_ID_OF_THE_RECORDER');will get a reference to the recorder which replaced the
<piperecorder...>
HTML element with the id UNIQUE_ID_OF_THE_RECORDER
.
To make sure all the recorder object/objects have been initialized and they're ready you must execute PipeSDK.getRecorderById()
only once the PipeSDK.onRecordersInserted()
method fires.
Example: add this JS code to your HTML page to be notified when the user clicks the record button in the desktop recorder:
<script> PipeSDK.onRecordersInserted = function(){ myRecorderObject = PipeSDK.getRecorderById('UNIQUE_ID_OF_THE_RECORDER'); myRecorderObject.btRecordPressed = function(id){ var args = Array.prototype.slice.call(arguments); console.log("btRecordPressed("+args.join(', ')+")"); } } </script>
When using the v2.0 JavaScript version of the embed code, the recorder object is retrieved in the callback function of the PipeSDK.insert()
method. This is where you can override the event functions.
Example: add this JS code to your app to insert a recorder in the app and get notified via console.log when the user clicks the record button in the desktop recorder:
PipeSDK.insert('UNIQUE_ID_OF_THE_RECORDER', paramsObject, function(myRecorderObject){ myRecorderObject.btRecordPressed = function(id){ var args = Array.prototype.slice.call(arguments); console.log("btRecordPressed("+args.join(', ')+")"); } });
The desktop recorder has 2 different set of events and corresponding event functions:
Below is the list of JavaScript event functions that the Pipe client will trigger when the user is recording a video from a desktop device.
onReadyToRecord(recorderId, recorderType)
Description: The Pipe recorder is ready to start recording videos(the interface has been built, you have allowed access to your webcam and you can see yourself in the browser)
Passed Parameters:
recorderId
- the recorder id
recorderType
- a string representing the type of the recorder (flash or HTML5).
Example:
myRecorderObject.onReadyToRecord = function(recorderId, recorderType) { var args = Array.prototype.slice.call(arguments); console.log("onReadyToRecord("+args.join(', ')+")"); });
userHasCamMic(recorderId,cam_number,mic_number)
Description: Pipe detects the number of cams and mics a user has
Passed Parameters:
recorderId
- the recorder id
cam_number
- number of web cam drivers the user has installed on his computer
mic_number
- number of sound card and sound sources the user has installed on his computer
Example:
myRecorderObject.userHasCamMic = function(recorderId,cam_number,mic_number){ var args = Array.prototype.slice.call(arguments); console.log("userHasCamMic("+args.join(', ')+")"); }
btRecordPressed(recorderId)
Description: RECORD button is pressed. This event does NOT mark the exact start of the recording. See onRecordingStarted
.
Passed Parameters:
recorderId
- the recorder id
Example:
myRecorderObject.btRecordPressed = function(recorderId){ var args = Array.prototype.slice.call(arguments); console.log("btRecordPressed("+args.join(', ')+")"); }
btStopRecordingPressed(recorderId)
Description: STOP RECORD button is pressed
Passed Parameters:
recorderId
- the recorder id
Example:
myRecorderObject.btStopRecordingPressed = function(recorderId){ var args = Array.prototype.slice.call(arguments); console.log("btStopRecordingPressed("+args.join(', ')+")"); }
btPlayPressed(recorderId)
Description: PLAY button is pressed
Passed Parameters:
recorderId
- the recorder id
Example:
myRecorderObject.btPlayPressed = function(recorderId){ var args = Array.prototype.slice.call(arguments); console.log("btPlayPressed("+args.join(', ')+")"); }
btPausePressed(recorderId)
Description: PAUSE button is pressed
Passed Parameters:
recorderId
- the recorder id
Example:
myRecorderObject.btPausePressed = function(recorderId){ var args = Array.prototype.slice.call(arguments); console.log("btPausePressed("+args.join(', ')+")"); }
onUploadDone(recorderId, streamName, streamDuration, audioCodec, videoCodec, fileType, audioOnly, location)
Description: Recorded data finishes streaming/uploading to the media server
Passed Parameters:
recorderId
- the recorder id
streamName
- a string representing the name of the stream WITHOUT the file extension
streamDuration
- the duration of the recording/audio file in seconds but accurate to the millisecond (like this: 4.322)
audioCodec
- the audio codec used for the recording
videoCodec
- the video codec used for the recording
fileType
- the initial file extension for the recording: flv or webm
audioOnly
- true if it is an audio only recording, false otherwise
location
- will take one of 3 values:
location
contains the subdomain of the Amazon S3 region where the final recording and snapshot will be stored by Pipe. For the EU region, for example, the recording will be stored at https://eu1-addpipe.s3.eu-central-1.amazonaws.com/ACCOUNT_HASH/FILE_NAME.mp4. The snapshot will be at the same location but with the .jpg extension. If Do Not Store Files is turned on the final video will not be stored in this location.
Example:
myRecorderObject.onUploadDone = function(recorderId, streamName, streamDuration, audioCodec, videoCodec, fileType, audioOnly, location){ var args = Array.prototype.slice.call(arguments); console.log("onUploadDone("+args.join(', ')+")"); }
onUploadProgress(recorderId, percent)
Description: Triggers everytime upload progress is made.
Passed Parameters:
recorderId
- the recorder id
percent
- the percent at which the upload progress is at
Example:
myRecorderObject.onUploadProgress = function(recorderId, percent){ var args = Array.prototype.slice.call(arguments); console.log("onUploadProgress("+args.join(', ')+")"); }
onCamAccess(recorderId, allowed)
Description:
onCamAccess
is triggered:
onCamAccess
being called at any time during Pipe client's lifetime. The function is triggered even if the user clicks the selected/active radio button.Flash Player's Privacy Panel when presented by the Pipe recorder client:
Internet browsers like Chrome will ask again for permission to use the webcam through a separate dialog box:
At the moment there is no way to catch the user's response to Chrome's dialog box.
Chrome will intelligently pause Flash content to save battery life.
This applies to smaller Pipe embeds too.
When Pipe is paused by Chrome, onCamAccess
will be called, while the Pipe recorder is apparently paused, if all these 3 conditions are met:
sis:1
in the embed code)In this scenario onCamAccess
will be called, followed by onFlashReady
, while the Pipe recorder is apparently paused.
Here's how Pipe looks when it's paused by Chrome:
Use 400x300px size or bigger for Pipe embeds to prevent it from being paused by Chrome.
Passed Parameters:
recorderId
- the recorder id
allowed
is true if:
Example:
myRecorderObject.onCamAccess = function(recorderId, allowed){ var args = Array.prototype.slice.call(arguments); console.log("onCamAccess("+args.join(', ')+")"); }
onPlaybackComplete(recorderId)
Description: Pipe finishes playback of recording stream
Passed Parameters:
recorderId
- the recorder id
Example:
myRecorderObject.onPlaybackComplete = function(recorderId){ var args = Array.prototype.slice.call(arguments); console.log("onPlaybackComplete("+args.join(', ')+")"); }
onRecordingStarted(recorderId)
Description: the Pipe desktop client started recording. This event is called ONLY if there's data to record and, when it is called, it will be called with a 200-220ms delay after the record button is pressed and the btRecordPressed
event is triggered.
Passed Parameters:
recorderId
- the recorder id
Example:
myRecorderObject.onRecordingStarted = function(recorderId){ var args = Array.prototype.slice.call(arguments); console.log("onRecordingStarted("+args.join(', ')+")"); }
onConnectionClosed(recorderId)
Description: the connection to the media server has failed completely (the connection could not be reestablished even after the 30 reconnection attempts in the HTML5 recorder)
Passed Parameters:
recorderId
- the recorder id
Example:
myRecorderObject.onConnectionClosed = function(recorderId){ var args = Array.prototype.slice.call(arguments); console.log("onConnectionClosed("+args.join(', ')+")"); }
onFPSChange(recorderId,currentFPS)
This function is not triggered by the HTML 5 recorder, only by the Flash one.
Description: called by the Pipe desktop Flash client every second with the current FPS value
Passed Parameters:
recorderId
- the recorder id
currentFPS
- the current frames-per-second that the Pipe desktop client reports (during recording, playback, uploading or saving) depending of the state of the Pipe desktop client
Example:
myRecorderObject.onFPSChange = function(recorderId,currentFPS){ var args = Array.prototype.slice.call(arguments); console.log("onFPSChange("+args.join(', ')+")"); }
onConnectionStatus(recorderId, status)
Description: Called by the Pipe desktop client for every connection event
Passed Parameters:
status
- the actual connection status:
Flash only
HTML5 only
recorderId
- value of recorderId
property of flashvars
object in the embed code
Example:
myRecorderObject.onConnectionStatus = function(recorderId, status){ var args = Array.prototype.slice.call(arguments); console.log("onConnectionStatus("+args.join(', ')+")"); }
onMicActivityLevel(recorderId, currentActivityLevel)
Description: the function is called by the Pipe desktop client every 10th of a second (100 milliseconds) with the current microphone level.
Passed Parameters:
recorderId
- the recorder id
currentActivityLevel
- The amount of sound the microphone is detecting in numeric values between 0 and 100. From our experience it's hard to get values over 50 though.
Example:
myRecorderObject.onMicActivityLevel = function(recorderId, currentActivityLevel){ var args = Array.prototype.slice.call(arguments); console.log("onMicActivityLevel("+args.join(', ')+")"); }
onSaveOk(recorderId, streamName, streamDuration, cameraName, micName, audioCodec, videoCodec, filetype, videoId, audioOnly, location)
Description: The recording data has been fully streamed to our media servers for further processing.
This is not a confirmation that the recorded file is ready for delivery as the recording will take a few seconds to be processed (conversion to .mp4, snapshot extraction, rotation, push to storage location).
Use Pipe's webhooks to be notified when the recording is fully processed and ready for delivery.
Passed Parameters:
recorderId
- the recorder id
streamName
- a string representing the name of the stream WITHOUT the file extension
streamDuration
- the duration of the recorded video/audio file in seconds but accurate to the millisecond (like this: 4.322)
cameraName
- the name of the webcam driver the user has selected for capturing video data
micName
- the name of the sound card/mic driver the user has selected for capturing audio data
audioCodec
- the audio codec used for the recording
videoCodec
- the video codec used for the recording
fileType
- the initial file extension for the recording: flv or webm
videoId
- a string representing the recording id in Pipe's database (same recording id that is sent through the webhook)
audioOnly
- true if it is an audio only recording, false otherwise
location
- will take one of 3 values:
location
contains the subdomain of the Amazon S3 region where the final recording and snapshot will be stored by Pipe. For the EU region, for example, the recording will be stored at https://eu1-addpipe.s3.eu-central-1.amazonaws.com/ACCOUNT_HASH/FILE_NAME.mp4. The snapshot will be at the same location but with the .jpg extension. If Do Not Store Files is turned on the final video will not be stored in this location.
Example:
myRecorderObject.onSaveOk = function(recorderId, streamName, streamDuration, cameraName, micName, audioCodec, videoCodec, fileType, videoId, audioOnly, location){ var args = Array.prototype.slice.call(arguments); console.log("onSaveOk("+args.join(', ')+")"); }
onFlashReady(recorderId)
This function is deprecated
Description: onFlashReady(recorderId);
is called when the recording UI has been built (after clicking "Record Video or Record Audio" on both the initial screen and on the camera/mic selection screen which shows up if you have more than 1 cam/mic) and Flash is ready to accept calls to the JS Control API v2.0 from HTML/JS
Chrome will intelligently pause Flash content to save battery life.
This applies to smaller Pipe embeds too.
When Pipe is paused by Chrome, onFlashReady
will be called, while the Pipe recorder is apparently paused, if these 2 conditions are met:
sis:1
in the embed code)In this scenario onFlashReady
will be called while the Pipe recorder is apparently paused.
If the user has also previously checked [ ] Remember in FP's Privacy panel onCamAccess
will be called, followed by onFlashReady
, while the Pipe recorder is apparently paused.
Here's how Pipe looks when it's paused by Chrome:
Use 400x300px size or bigger for Pipe embeds to prevent it from being paused by Chrome.
Passed Parameters:
recorderId
- the recorder id
Example:
myRecorderObject.onFlashReady = function(recorderId){ var args = Array.prototype.slice.call(arguments); console.log("onFlashReady("+args.join(', ')+")"); }
Below is the list of JavaScript events that the Pipe client will dispatch when the user is UPLOADING an existing video using the desktop recorder. You can turn on the feature from your embed code or from the Pipe account area when generating an embed code, details here.
onDesktopVideoUploadStarted(recorderId, filename, filetype, audioOnly)
Description: The user has selected a recording from the computer's library and the recording is ready for upload.
Passed Parameters:
recorderId
- the recorder id
filename
- the (automatically generated) name of the recording without extension
filetype
- the file extension of the uploaded video, it can be mp4, mov, 3gp, m4v, mkv, avi, mp3, wma etc.
audioOnly
- true if we're expecting an audio only recording, false otherwise
Example:
myRecorderObject.onDesktopVideoUploadStarted = function(recorderId, filename,filetype, audioOnly){ var args = Array.prototype.slice.call(arguments); console.log("onDesktopVideoUploadStarted("+args.join(', ')+")"); }
onDesktopVideoUploadSuccess(recorderId, filename, filetype, videoId, audioOnly, location)
Description: The recording has finished uploading successfully.
Passed Parameters:
recorderId
- the recorder id
filename
- the automatically generated name of the recording
filetype
- the file extension of the uploaded video, it can be mp4, mov, 3gp, m4v, mkv, avi, mp3, wma etc.
videoId
- a string representing the recording id in Pipe's database (same recording id that is sent through the webhook)
audioOnly
- true if it is an audio only recording, false otherwise
location
- will take one of 3 values:
location
contains the subdomain of the Amazon S3 region where the final recording and snapshot will be stored by Pipe. For the EU region, for example, the recording will be stored at https://eu1-addpipe.s3.eu-central-1.amazonaws.com/ACCOUNT_HASH/FILE_NAME.mp4. The snapshot will be at the same location but with the .jpg extension. If Do Not Store Files is turned on the final video will not be stored in this location.
Example:
myRecorderObject.onDesktopVideoUploadSuccess = function(recorderId, filename,filetype,videoId,audioOnly,location){ var args = Array.prototype.slice.call(arguments); console.log("onDesktopVideoUploadSuccess("+args.join(', ')+")"); }
onDesktopVideoUploadProgress(recorderId, percent)
Description: Triggers everytime upload progress is made.
Passed Parameters:
recorderId
- the recorder id
percent
- the percent at which the upload progress is at
Example:
myRecorderObject.onDesktopVideoUploadProgress = function(recorderId, percent){ var args = Array.prototype.slice.call(arguments); console.log("onDesktopVideoUploadProgress("+args.join(', ')+")"); }
onDesktopVideoUploadFailed(recorderId, error)
Description: There was an error while uploading the recording.
Passed Parameters:
recorderId
- the recorder id
error
- The error thrown when the upload failed to complete
Example:
myRecorderObject.onDesktopVideoUploadFailed = function(recorderId, error){ var args = Array.prototype.slice.call(arguments); console.log("onDesktopVideoUploadFailed("+args.join(', ')+")"); }
Every time something happens with the mobile native recorder (a video is starting to upload, an upload has finished, etc.) the recorder will execute a specific JavaScript function with information about the event.
You can add these mobile native recorder event functions to your HTML/JS app and extend them with your own code to do your bidding.
When using the v1.0 embed code you can just add these JS event functions to your HTML page. The Pipe mobile native recorder will detect their presence and execute them when needed.
Try adding the code below immediately after your v1 Pipe recorder embed code:
<script> function onVideoRecorded(filename,filetype, audioOnly){ var args = Array.prototype.slice.call(arguments); alert("onVideoRecorded("+args.join(', ')+")"); } </script>
An alert will pop up in your web page whenever you close the iOS/Android controlled recording UI.
You can replace onVideoRecorded(filename,filetype, audioOnly)
in the example above with any of the mobile event functions below.
onVideoRecorded(filename, filetype, audioOnly);
Description: The user has recorded a new video or chosen an existing video from the device's library and the video is ready for upload.
Passed Parameters:
filename
- the (automatically generated) name of the recording without extension
filetype
- the file extension of the uploaded video, it can be mp4, mov, 3gp, m4v, etc.
audioOnly
- true if we're expecting an audio only recording, false otherwise
Example:
function onVideoRecorded(filename,filetype, audioOnly){ var args = Array.prototype.slice.call(arguments); alert("onVideoRecorded("+args.join(', ')+")"); }
onClickUpload();
Description: Triggered when the upload button is clicked.
Passed Parameters: None
Example:
function onClickUpload(){ var args = Array.prototype.slice.call(arguments); alert("onClickUpload("+args.join(', ')+")"); }
onVideoUploadSuccess(filename, filetype, videoId, audioOnly, location);
Description: The new or existing recording has finished uploading successfully.
Passed Parameters:
filename
- the automatically generated name of the recording
filetype
- the file extension of the uploaded video, it can be mp4, mov, 3gp, m4v, etc.
videoId
- a string representing the recording id in Pipe's database (same recording id that is sent through the webhook)
audioOnly
- true if it is an audio only recording, false otherwise
location
- will take one of 3 values:
location
contains the subdomain of the Amazon S3 region where the final recording and snapshot will be stored by Pipe. For the EU region, for example, the recording will be stored at https://eu1-addpipe.s3.eu-central-1.amazonaws.com/ACCOUNT_HASH/FILE_NAME.mp4. The snapshot will be at the same location but with the .jpg extension. If Do Not Store Files is turned on the final video will not be stored in this location.
Example:
function onVideoUploadSuccess(filename,filetype,videoId,audioOnly,location){ var args = Array.prototype.slice.call(arguments); alert("onVideoUploadSuccess("+args.join(', ')+")"); }
onVideoUploadProgress(percent);
Description: Triggers everytime upload progress is made.
Passed Parameters:
percent
- the percent at which the upload progress is at
Example:
function onVideoUploadProgress(percent){ var args = Array.prototype.slice.call(arguments); alert("onVideoUploadProgress("+args.join(', ')+")"); }
onVideoUploadFailed(error);
Description: There was an error while uploading the recording.
Passed Parameters:
error
- The error thrown when the upload failed to complete
Example:
function onVideoUploadFailed(error){ var args = Array.prototype.slice.call(arguments); alert("onVideoUploadFailed("+args.join(', ')+")"); }
Every time something happens with the mobile native recorder (a video is starting to upload, an upload has finished, etc.) the recorder will execute a specific JavaScript function with information about the event.
You can add these mobile native recorder event functions to your HTML/JS app and extend them with your own code to do your bidding.
Since the v2.0 embed code supports multiple recorders on the same page, to override a recorder's event functions, we need to get the desired recorder object 1st.
This is done differently depending on what version of the embed code you are using.
When using the v2.0 HTML embed code you can use the PipeSDK.getRecorderById()
method to get a reference to a recorder object.
For example:
var myRecorderObject = PipeSDK.getRecorderById('UNIQUE_ID_OF_THE_RECORDER');will get a reference to the recorder which replaced the <piperecorder> HTML element with the id
UNIQUE_ID_OF_THE_RECORDER
.
To make sure all the recorder object/objects have been initialized and they're ready you must execute PipeSDK.getRecorderById()
only once the PipeSDK.onRecordersInserted()
method fires.
Example: add this JS code to your HTML page to be notified when the upload starts after the user has recorded a video in the iOS/Android controlled UI:
<script> PipeSDK.onRecordersInserted = function(){ myRecorderObject = PipeSDK.getRecorderById('UNIQUE_ID_OF_THE_RECORDER'); myRecorderObject.onVideoUploadStarted = function(id, filename, filetype, audioOnly){ var args = Array.prototype.slice.call(arguments); console.log("onVideoUploadStarted("+args.join(', ')+")"); } } </script>
When using the v2.0 JavaScript version of the embed code, the recorder object is retrieved in the callback function of the PipeSDK.insert()
method. This is where you can override the event functions.
Example: add this JS code to your app to insert a recorder in the app and get notified via console.log when the upload starts after the user has recorded a video in the iOS/Android controlled UI:
PipeSDK.insert('UNIQUE_ID_OF_THE_RECORDER', paramsObject, function(myRecorderObject){ myRecorderObject.onVideoUploadStarted = function(id, filename, filetype, audioOnly){ var args = Array.prototype.slice.call(arguments); console.log("onVideoUploadStarted("+args.join(', ')+")"); } });
You can replace onVideoUploadStarted(id, filename, filetype, audioOnly)
in the example above with any of the 2.0 mobile event functions below.
onVideoUploadStarted(recorderId, filename, filetype, audioOnly)
Description: The user has recorded a new video or chosen an existing video from the device's library and the video is ready for upload.
Passed Parameters:
recorderId
- the recorder id
filename
- the (automatically generated) name of the recording without extension
filetype
- the file extension of the uploaded video, it can be mp4, mov, 3gp, m4v, etc.
audioOnly
- true if we're expecting an audio only recording, false otherwise
Example:
myRecorderObject.onVideoUploadStarted = function(recorderId, filename,filetype, audioOnly){ var args = Array.prototype.slice.call(arguments); console.log("onVideoUploadStarted("+args.join(', ')+")"); }
onVideoUploadSuccess(recorderId, filename, filetype, videoId, audioOnly, location)
Description: The new or existing recording has finished uploading successfully.
Passed Parameters:
recorderId
- the recorder id
filename
- the automatically generated name of the recording
filetype
- the file extension of the uploaded video, it can be mp4, mov, 3gp, m4v, etc.
videoId
- a string representing the recording id in Pipe's database (same recording id that is sent through the webhook)
audioOnly
- true if it is an audio only recording, false otherwise
location
- will take one of 3 values:
location
contains the subdomain of the Amazon S3 region where the final recording and snapshot will be stored by Pipe. For the EU region, for example, the recording will be stored at https://eu1-addpipe.s3.eu-central-1.amazonaws.com/ACCOUNT_HASH/FILE_NAME.mp4. The snapshot will be at the same location but with the .jpg extension. If Do Not Store Files is turned on the final video will not be stored in this location.
Example:
myRecorderObject.onVideoUploadSuccess = function(recorderId, filename,filetype,videoId,audioOnly,location){ var args = Array.prototype.slice.call(arguments); console.log("onVideoUploadSuccess("+args.join(', ')+")"); }
onVideoUploadProgress(recorderId, percent)
Description: Triggers everytime upload progress is made.
Passed Parameters:
recorderId
- the recorder id
percent
- the percent at which the upload progress is at
Example:
myRecorderObject.onVideoUploadProgress = function(recorderId, percent){ var args = Array.prototype.slice.call(arguments); console.log("onVideoUploadProgress("+args.join(', ')+")"); }
onVideoUploadFailed(recorderId, error)
Description: There was an error while uploading the recording.
Passed Parameters:
recorderId
- the recorder id
error
- The error thrown when the upload failed to complete
Example:
myRecorderObject.onVideoUploadFailed = function(recorderId, error){ var args = Array.prototype.slice.call(arguments); console.log("onVideoUploadFailed("+args.join(', ')+")"); }
The REST API allows you to request information from our servers programmatically and in a standardized manner, using JSON.
All requests are made against https://api.addpipe.com
and are authenticated by sending the API key as the value of the X-PIPE-AUTH
header.
The API Key can be found in your Pipe account details page and it should be kept in a safe place, like any other password. If compromised, the API key can be replaced with a new one.
/video
Perform actions for (undeleted) recordings from your account.
all
, optional. May be included or omitted from the request.GET https://api.addpipe.com/video/all
- get all videos from your account. JSON response/video/:id
Perform actions for a specific recording.
:id
- numerical representation of the recording ID which can be found in your Pipe account, under the Recordings tab.GET https://api.addpipe.com/video/167895864
- get specific information for this recording id JSON responseDELETE https://api.addpipe.com/video/167841
- deletes the recording with this idNote: you can now also automatically delete recordings after a number of days thorugh the new ">lifecycle feature available on the environment edit page.
/account
Perform actions on your account.
GET https://api.addpipe.com/account
- get information regarding your Pipe account JSON response/environment
Access environment related information.
GET https://api.addpipe.com/environment
- get information regarding your environments JSON response/environment/:id
Get details about a specific environment.
:id
- numerical representation of the environment unique ID which can be retrieved by using the GET /environment
endpointGET https://api.addpipe.com/environment/1537
- get specific information for this environment id JSON response/webhook
Access webhook related information.
GET https://api.addpipe.com/webhook
- get information regarding your webhooks JSON response/webhook/:id
Perform actions for a specific webhook.
:id
- the numeric webhook id which can be retrieved by using the GET /webhook
endpoint.PUT https://api.addpipe.com/webhook/69
- update your webhook by following the below JSON scheme{ "webhook": "http://your-fancy-website.com/webhook", "webhook_recorded": "0", "webhook_transcoded": "1", "webhook_converted": "1", "webhook_copied_pipe_s3":"0", "webhook_copied_s3": "0", "webhook_copied_ftp": "0", "webhook_copied_dbox": "0", "active":"1" }
/amazon
Perform actions on your AWS S3 related information stored with Pipe.
GET https://api.addpipe.com/amazon
- retrieve basic information about your AWS S3 credentials for every environment JSON response/amazon/:id
Perform actions for a specific Amazon S3 credentials set.
:id
- numerical representation of the Amazon S3 credentials ID which can be retrieved by using the GET /amazon
endpoint.PUT https://api.addpipe.com/amazon/69
- update your Amazon credentials following the below JSON scheme{ "amz_key": "YourAmazonKey", "amz_secret": "YourAmazonSecret", "amz_bucket": "TheBucket", "amz_bucket_region": "us-east-1" }
/ftp
Perform actions on your FTP/SFTP related information stored with Pipe.
GET https://api.addpipe.com/ftp
- get information regarding your (S)FTP credentials JSON response/ftp/:id
Perform actions for a specific (S)FTP credentials set.
:id
- the numerical id of the (S)FTP credentials set. It can be retrieved by using the GET /ftp
endpoint.PUT https://api.addpipe.com/ftp/69
- update your (S)FTP credentials following the below JSON scheme{ "ftp_host": "FtpHost", "ftp_port": "21", "ftp_username": "FtpUsername", "ftp_password": "FtpPass", "ftp_dir": "/dir/to/saved_videos", "sftp_host": "SftpHost", "sftp_port": "22", "sftp_username": "SftpUser", "sftp_password": "SftpPass" "sftp_dir": "/dir/to/saved_videos" }
/dropbox
Perform actions on your Dropbox related information stored with Pipe.
GET https://api.addpipe.com/dropbox
- get some of the information around your Dropbox credentials JSON response/dropbox/:id
Perform actions for a specific Dropbox credentials set.
:id
- the numeric id for the Dropbox credentials set, it can be obtained through GET /dropbox
endpoint.PUT https://api.addpipe.com/dropbox/69
- update your Dropbox credentials following the below JSON scheme{ "dbox_token": "YourDropboxAccessToken", "dbox_folder": "YourDropboxFolder" }
GET the info on a particular recording
$headers = array(
'x-pipe-auth: YOUR-PIPE-API-KEY'
);
// init curl object
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.addpipe.com/video/YOUR-RECORDING-ID');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Timeout in seconds
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$content = curl_exec($ch);
echo $content;
DELETE a recording
$headers = array(
'x-pipe-auth: YOUR-PIPE-API-KEY'
);
// init curl object
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.addpipe.com/video/YOUR-RECORDING-ID');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Timeout in seconds
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$content = curl_exec($ch);
echo $content;
PUT a new set of AWS S3 credentials
var data = JSON.stringify({
"amz_key": "",
"amz_secret": "",
"amz_bucket": "",
"amz_bucket_region": ""
});
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
console.log(this.responseText);
}
});
xhr.open("PUT", "https://api.addpipe.com/amazon");
xhr.setRequestHeader("x-pipe-auth", "Your-Pipe-Api-Key");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.send(data);
PUT a new set of AWS S3 credentials
package main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "https://api.addpipe.com/amazon"
payload := strings.NewReader("{\n \"amz_key\": \"\",\n \"amz_secret\": \"\",\n \"amz_bucket\": \"\",\n \"amz_bucket_region\": \"\"\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("x-pipe-auth", "Your-Pipe-Api-Key")
req.Header.Add("content-type", "application/json")
req.Header.Add("cache-control", "no-cache")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(res)
fmt.Println(string(body))
}
PUT a new set of AWS S3 credentials
import http.client
conn = http.client.HTTPConnection("api.addpipe.com")
payload = "{\n \"amz_key\": \"\",\n \"amz_secret\": \"\",\n \"amz_bucket\": \"\",\n \"amz_bucket_region\": \"\"\n}"
headers = {
'x-pipe-auth': "Your-Pipe-Api-Key",
'content-type': "application/json",
'cache-control': "no-cache"
}
conn.request("PUT", "/account", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
PUT a new set of AWS S3 credentials
require 'uri'
require 'net/http'
url = URI("https://api.addpipe.com/amazon")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Put.new(url)
request["x-pipe-auth"] = 'Your-Pipe-Api-Key'
request["content-type"] = 'application/json'
request["cache-control"] = 'no-cache'
request.body = "{\n \"amz_key\": \"\",\n \"amz_secret\": \"\",\n \"amz_bucket\": \"\",\n \"amz_bucket_region\": \"\"\n}"
response = http.request(request)
puts response.read_body
PUT a new set of AWS S3 credentials
wget --quiet \
--method PUT \
--header 'x-pipe-auth: Your-Pipe-Api-Key' \
--header 'content-type: application/json' \
--header 'cache-control: no-cache' \
--body-data '{\n "amz_key": "",\n "amz_secret": "",\n "amz_bucket": "",\n "amz_bucket_region": ""\n}' \
--output-document \
- https://api.addpipe.com/amazon
PUT a new set of AWS S3 credentials
curl --request PUT \
--url https://api.addpipe.com/amazon \
--header 'cache-control: no-cache' \
--header 'content-type: application/json' \
--header 'x-pipe-auth: Your-Pipe-Api-Key' \
--data '{\n "amz_key": "",\n "amz_secret": "",\n "amz_bucket": "",\n "amz_bucket_region": ""\n}'