Documentation

Embedding your first recorder


Embeding from the Pipe account area

To embed your first recorder on your website follow these 4 steps:

  1. Sign in to your Pipe account area and go to the Embed Recorder section
  2. In the lower right area you'll find the 1.0 and 2.0 beta embed codes. Copy the preferred one
  3. Paste the code in your HTML page and make sure to save or upload the modified page back to your website
  4. Refresh the page in your browser on your desktop or mobile device

The Pipe recording client will detect mobile and desktop browsers and load the corresponding video recorder client.

3 types of embed code

You'll find 3 types of embed codes in the embed section of the account area.

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 solves all of the problems we had with the 1st version.

The HTML version relies on HTML tags for easy integration with any HTML page. It will be our default embed code.

The 2.0 embed code solves all of the problems we had with the 1st version.

This Java Script version makes it easy to use Pipe with JS heavy single page web apps including those built using React, Angular or Vue.js.

You can use it to dinamically insert, remove and control recorders in the page. It will load pipe.js so that its ready and waiting whenever you want to add a recorder.

Adding multiple recorders to the page

One of the new things you can do with our new v2.0 embed code is to add multiple recorders to the HTML page.

v2.0 HTML

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="//s1.addpipe.com/2.0/pipe.css"/>
<script type="text/javascript" src = "//s1.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.

v2.0 JavaScript

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="//s1.addpipe.com/2.0/pipe.css"/>
<script type="text/javascript" src = "//s1.addpipe.com/2.0/pipe.js"></script>

<script type="text/javascript">
var pipeParams1 = {size: {width:400,height:330}, qualityurl: "avq/300p.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.

Viewing recordings on your account


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.

Requirements and supported browsers


Pipe officially supports the following browsers.


💻 On Desktop:

  • HTML5 recorder

    • webcam recording: Chrome 63+ and Firefox 50+ on secure origins (https)
    • screen recording: Chrome 63+ on secure origins (https)

  • Flash recorder:
    • Firefox 35 and up
    • Chrome 4 and up
    • Safari 4 and up
    • Internet Explorer 9 and up
    • Edge 12

📱 On Mobile:

  • Android Browser on Android version 4.4 and up
  • Safari on iOS 6 and up

💻 On Desktop:

  • HTML5 recorder

    • webcam recording: Chrome 63+ and Firefox 50+ on secure origins (https)
    • screen recording: Chrome 63+ on secure origins (https)

  • Flash recorder:
    • Firefox 35 and up
    • Chrome 4 and up
    • Safari 4 and up
    • Internet Explorer 11
    • Edge 12 and up

📱 On Mobile:

  • Android Browser on Android version 4.4 and up
  • Safari on iOS 6 and up

Changing the recorder size


The space occupied by the recorder client differs between the desktop and mobile recorder client because the technology used is different and thus the UI is different.

Recorder size on desktop devices

The size of the recorder on desktop devices can be changed directly from the embed code or, when generating new embed codes, from our embed panel as shown below.

Changing when generating new embed codes

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.

Changing directly in the embed code

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 recorder on desktop devices.

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/300p.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.

Recorder size on mobile devices

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:

Height

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.

Width

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.

Container DIV

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:

Button

The button is a label element with the pipeFileInput CSS class applied which defaults to:

  1. a vertical linear grey gradient
  2. 1px solid #999 border
  3. 10px padding all around and 3px rounded corner
  4. it inherits whatever fonts and font sizes are used in your website CSS
  5. 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

You can overwrite the pipeFileInput CSS class in your CSS.

Colors and rounded corners


Desktop recorder

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).

Colors & rounded corners

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:

  1. the radius of the 4 corners of the recorder
  2. the background color shown in the inital screen
  3. the bottom menu background color
  4. the normal and muse over colors for the text buttons in the initial screen

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/300p.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/300p.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/300p.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"};

Mobile recorder

Pipe's mobile 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.

1.0 embed code

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

2.0 embed code

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 byb the 2.0 embed code for the recorder button shown on mobile browsers see below.

Hiding the bottom control menu

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. 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:

Limiting the length of recordings


Recordings from desktop devices

Recordings from desktop devices 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.

New embed codes

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 videos recorded on the spot from desktop devices to your specified length.

The value is in seconds.

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 mrt propery of the flashvars object in your embed code. The default value is 120 seconds.

var flashvars = {qualityurl: "avq/300p.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/300p.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/300p.xml",accountHash:"1edfef4c4967d69b7129ec3ffa534002", eid:1, showMenu:"true", mrt:120,sis:0,asv:1,mv:0, dpv:0, ao:0, dup:0};

Recordings from mobile devices

When recording from mobile browsers like Safari on iOS and Chrome on Android 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.

Cut mobile videos to length

However, in Pipe, there is an option to cut mobile videos to the max length specified in the embed code (as shown above in the desktop section) if the video uploaded from mobile is longer.

The option can be found in the environment's settings which can be reached by clicking the cog wheel on the right side of the top tabbed menu.

When relying on this mechanism you should advise your mobile users that their videos 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.

Allowing file uploads from desktop


By default, on desktop, 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:

New embed codes

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.

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:

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/300p.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/300p.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.

Supported file types (containers)

We’re currently allowing users to upload the following video & audio file types:

VideoAudio
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.

This feature is currently in beta.

Audio and video quality


With Pipe you have strong control over the quality of the videos recorded on desktop devices while on mobile devices the quality depends 100% on the device.

Picture quality on desktop devices

On desktop computers the picture quality depends on the audio/video quality profile you selected for your embed code but also on the quality of the webcam (affects resolution and fps) and light available in the room (low light results in lower fps).

Pipe offers 4 predefined quality profiles:

  • 240p : 320x240px @ 30 FPS
  • 300p : 400x300px @ 30 FPS (default)
  • 480p : 640x480px @ 30 FPS
  • 720p : 1280x720px @ 30 FPS (HD)

To use one of the predefined quality profiles (240p, 300p, 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 more control over the resolution (like for example if you want to record square videos) you can also create and use your own quality profiles. See using your own quality profiles for more information.

The resolution is not affected by the recorder size in the HTML page. You can have a 640x480 recorder embedded on your page that records videos at 1280x720 resolution.

On desktop, all videos (from both the HTML 5 recorder and the legacy Flash recorder) are converted by Pipe to 30 FPS.

Audio quality on desktop devices

The legacy Flash recorder will record mono Nellymoser ASAO audio at 44.1 kHz.

The newer HTML5 recorder will record mono or stereo Opus audio at 48 kHz. 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+). Chrome and Firefox will also apply noise suppression, audio echo cancellation and auto gain filters.

Both ASAO and Opus audio will be converted by Pipe to AAC for the final .mp4 file.

Picture quality on mobile devices

The picture quality and resolution for recordings made with a mobile device depend on the device capabilities and the video recording settings on the device.

For example, from iOS, a user could upload videos in various resolutions, depending on how that video is recorded:

  • If, when prompted,the user records a new video, that video will be recorded at 360x480 (portrait) and 480x360 (landscape) at 30 FPS
  • If, when prompted, the user chooses an existing video, that video will be compressed by iOS in terms of bitrate (the resolution and FPS will remain the same)

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.

Audio quality on mobile devices

When uploading a video from mobile devices the audio codec and sample rate will depend on the device itself and the OS. We've mostly seen AAC audio at 48kHz but ocasionally 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.

Using your own quality profiles


Pipe allows you to use your own quality profile (XML file hosted on your website) 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 from desktop devices.

Step 1: create your own quality profile file and host it

Here are the 4 quality profiles available through the Pipe account area: 240p, 300p, 480p and 720p. Download one, make your changes and upload it to your website.

Here's what you can change and what recorder it will affect:

  • Flash desktop recorder:
    • bytes/second
    • picture quality
    • fps and kfps
    • width and height
  • HTML5 desktop recorder:
    • width and height

Step 2: link to the new .xml file in your Pipe embed


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 so qualityurl: ('https:' == document.location.protocol ? 'https://' : 'http://') +"yourdomain.com/quality_profile.xml". Your custom object will be passed as a parameter to PipeSDK.insert()

Step 3: allow Pipe to load the .xml file from your website

In order for Pipe to be able to load your custom .xml video quality profile, you will need to do the following:

  1. Create a crossdomain.xml policy file (necessary for the Flash client) and put it in the root of your website. Here is the cross domain policy file that allows Pipe to load video quality profiles from your website:
    <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.
  2. Enable CORS on the server on which you are hosting the custom .xml video quality profile (necessary for the HTML5 client). For example on Apache, one of the most commonly used webservers, to add the CORS authorization to the header you must simply add the following line in either the 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://s1.addpipe.com"
    or if you are using the CDN
    Header set Access-Control-Allow-Origin "https://cdn.addpipe.com"
    Also make sure you are using the same protocol depending if your site has SSL enabled or not.

    For more details on how to configure CORS on other servers see https://enable-cors.org/server.html

CSS classes in the v2 embed code


Our newer 2.0 embed code uses this CSS file to control the look and feel of the HTML5 recorder and Mobile recorder. Overwriting the CSS classed below will have no effect on our legacy Flash recorder which is 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 classes
Name 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

Mobile classes
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

How to override the CSS classes

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 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 will have a smaller font size.

Working directly with the embed code


You can change most of the recorder settings directly in your embed code. Size, quality, colors, the maximum recording time, payload data and more can all be changed by editing the embed code.

For example to change the size of the recorder on desktop just change the width and height values on this line: var size = {width:320, height:270};.

var flashvars will contain an array of different settings that you can change:

Name Description
qualityurl is the path to the quality profile. Right now, you can choose between avq/240p.xml, avq/300p.xml, avq/480p.xml and avq/720p.xml or it can be the path to your custom quality profile (affects only the quality on desktop devices)
accountHash this is the hash value of your account, this value should not be changed
eid this is the ID of the current environment. This is set to 1 by default. It can be changed to any other enviroment id that you have created. You can get the enviroment from the Edit your Pipe enviroment page
showMenu true if the control menu will be visible or false if it won't
mrt the maximum recording time in seconds (works only on desktop devices)
asv short for auto save video. When set to 1, the recordings will automatically be saved. When it is missing or set to 0 the recordings won't be automatically saved.
mv short for mirror video. When set to 1, Pipe will mirror the webcam stream horizontolly. The final recording will not be flipped. When it is missing or set to 0 the stream will not be mirrored
dpv When set to 1, Pipe will disable the option that allows the mobile client to upload a pre-recorded video
ao When set to 1, Pipe will record audio only.
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, skipping directly to the recording screen.
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.
ssb short for show settings buttons and goes hand in hand with the showMenu setting. When set to 0 will hide the microphone meter and icon when the recorder menu is not shown.
dup When set to 1 Pipe will allow to directly upload pre-recorded videos or audio files on desktop
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
recorderId a custom string that gets sent back with every function in the desktop JS Events API for the 1.0 embed code

You can customize any attribute of the piperecorder tag

All the attributes are prefixed by the pipe- prefix, otherwise they have the same names and control the same options as in v1 of the embed code

Name Description
pipe-width the width of the recorder in pixels
pipe-height the height of the recorder in pixels
pipe-qualityurl is the path to the quality profile. Right now, you can choose between avq/240p.xml,avq/480p.xml and avq/720p.xml or it can be the path to your custom quality profile (works only on desktop devices)
pipe-accountHash this is the hash value of your account. This value should not be changed
pipe-eid this is the ID of the current environment. This is set to 1 by default. It can be changed to any other enviroment id that you have created. You can get the enviroment from the Edit your Pipe enviroment page
pipe-showMenu 1 if the control menu will be visible or 0 if it won't
pipe-mrt the maximum recording time in seconds (works only on desktop devices)
pipe-asv short for auto save video. When set to 1, the recordings will automatically be saved. When it is missing or set to 0 the recordings won't be automatically saved.
pipe-mv short for mirror video. When set to 1, Pipe will mirror the webcam stream horizontolly. The final recording will not be flipped. When it is missing or set to 0 the stream will not be mirrored
pipe-dpv When set to 1, Pipe will disable the option that allows the mobile client to upload a pre-recorded video
pipe-ao When set to 1, Pipe will record audio only.
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, skipping directly to the recording screen.
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.
pipe-ssb short for show settings buttons and goes hand in hand with the showMenu setting. When set to 0 will hide the microphone meter and icon when the recorder menu is not shown.
pipe-dup When set to 1 Pipe will allow to directly upload pre-recorded videos or audio files
pipe-bgCol the background color of the recorder
pipe-cornerradius Controls the corner radius of the Pipe recorder
pipe-menuCol the color of the control menu of the recorder
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.

In version 2.0 of the embed code you have to initialize your own JavaScript object 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 like so: PipeSDK.insert('ID_OF_THE_DIV_TO_BE_REPLACED', YOUR_CUSTOM_OBJECT_NAME, CALLBACK_FUNCTION);

The callback function will return the actual recorder object like so:

PipeSDK.insert('my_ID', parametersObject, function(recorderObject){
    //custom code goes here
}

See control API and events API section for information on how the recorderObject can be used

The names of the object properties will remain the same and have the same effect as in version 1.0 of the embed code

Name Description
size object that contains the width and height for the recorder, as properties
qualityurl is the path to the quality profile. Right now, you can choose between avq/240p.xml,avq/480p.xml and avq/720p.xml or it can be the path to your custom quality profile (works only on desktop devices)
accountHash this is the hash value of your account. This value should not be changed
eid this is the ID of the current environment. This is set to 1 by default. It can be changed to any other enviroment id that you have created. You can get the enviroment from the Edit your Pipe enviroment page
showMenu 1 if the control menu will be visible or 0 if it won't
mrt the maximum recording time in seconds (works only on desktop devices)
asv short for auto save video. When set to 1, the recordings will automatically be saved. When it is missing or set to 0 the recordings won't be automatically saved.
mv short for mirror video. When set to 1, Pipe will mirror the webcam stream horizontolly. The final recording will not be flipped. When it is missing or set to 0 the stream will not be mirrored
dpv When set to 1, Pipe will disable the option that allows the mobile client to upload a pre-recorded video
ao When set to 1, Pipe will record audio only.
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, skipping directly to the recording screen.
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.
ssb short for show settings buttons and goes hand in hand with the showMenu setting. When set to 0 will hide the microphone meter and icon when the recorder menu is not shown.
dup When set to 1 Pipe will allow to directly upload pre-recorded videos or audio files
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.

Pipe in different languages


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.

Desktop

The Pipe desktop client 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.

Mobile

The Pipe mobile client auto-detects the preferred language setting of the mobile OS in which it is run (using HTTP Accept Language Headers) and will use that language if available.

Using your own language file


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()

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:

  1. Create a crossdomain.xml policy file (necessary for the Flash client) and put it in the root of your website. Here is the cross domain policy file that allows Pipe to load language files from your website:
    <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.
  2. Enable CORS on the server on which you are hosting the custom .xml language file (necessary for the HTML5 and Mobile client). For example on Apache, one of the most commonly used webservers, to add the CORS authorization to the header you must simply add the following line in either the 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://s1.addpipe.com"
    or if you are using the CDN
    Header set Access-Control-Allow-Origin "https://cdn.addpipe.com"
    Also make sure you are using the same protocol depending if your site has SSL enabled or not.

    For more details on how to configure CORS on other servers see https://enable-cors.org/server.html

HTML5 and Flash clients compared


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 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 bandwdith 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 bandwdith 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 Chrome 63+ and Firefox 50+ on pages delivered over https. See Requirements and supported browsers.
Permissions needed in browser Chrome or Firefox 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.

Differences in JavaScript Events API

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
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)

Differences in JavaScript Control API

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

Troubleshooting connection issues


Our desktop recorder works by streaming data in real time to a media server hosted by us. The connection type differs between the legacy Flash (rtmps) and HTML5 (wss) clients. Below we'll go through both types of connection so you can understand why a connection might fail and what you can do about it.

The connection process in the legacy Flash recording client

When connecting to the media server, the Flash client uses the RTMPS protocol to connect to our media server using port 443. This ensures the highest chance for the connection to go through from behind more restrictive networks like those in corporate or university environments.

The connection is established when the user presses the RECORD button

In case of a connection problem the Flash recording client will show one of 2 error messages:

Connection failed

If when the user presses RECORD the Connection Failed error message is shown, the user is unable to connect to our media server (using the Flash client).

Causes:

This happens when a firewall or a proxy on the user's computer or on the network he is connecting from prevents the rtmps connection from being established. This can happen because:

  1. the firewall/proxy inspects the packets and does not allow RTMPS packets
  2. the firewall/proxy does not allow outgoing connections to port 443
Your connection to the media server has failed

If after the initial successful connection to the media server, while recording, the connection fails and the recording client shows the Your connection to the media server has failed error message he is most probably having network or Internet connection issues.

Causes:

The disconnection happens AFTER a successfull rtmps connection has been established. This can happen because:

  1. A busy or high latency WiFi network might cause continuously open RTMPS connections to disconnect
  2. The Internet connection might actually fail (ISP problems, power failiure, tripping over the router, etc.)

The connection process in the HTML5 recording client

When connecting to our media server, the HTML5 client, starts with a long poll connection that's established between the HTML5 client and server using HTTPS on port 443. If the browser supports WebSockets the connection is upgraded right away to WSS (secured websockets) over port 443. If computer/network changes are made when the connection is live over WSS and if any of these changes prevent the use of WSS, the connection will automatically fallback to long-polling on HTTPS over port 443.

The connection is opened earlier than with the legacy Flash recorder client, as soon as the user presses [Record Video] or [Record Audio] on the initial recorder screen.

In case of a connection problem the HTML5 recording client will show one of 2 error messages:

Connection timeout

If when the user presses [Record Video] or [Record Audio] the Connection timeout error message is shown, the user is unable to connect to our media server (using the HTML5 client).

Causes:

This happens when a firewall or a proxy on the user's computer or on the network he is connecting from prevents the https long poll or wss connection (both towards port 443 on our media server) from being established. This can happen because:

  1. the firewall/proxy inspects the packets and does not allow https or wss packets towards our media server
  2. the firewall/proxy does not allow outgoing connections to port 443
Your connection to the server has been interrupted

Causes:

The disconnection happens AFTER a successfull wss connection has been established. This can happen because:

  1. A busy or high latency WiFi network might cause continuously open wss connections to disconnect
  2. The Internet connection might actually fail (ISP problems, power failiure, tripping over the router, etc.)

When the connection fails for any of the above reasons, the reconnection is not attempted.

Recording recovery mechanism

Both the Flash and HTML5 media servers have a recording recovery mechanism in place which recovers the recording if, during a recording, the connection fails. This mechanism triggers only if the autosave option is enabled in the embed code.

All the webhooks will trigger normally for recovered recordings. This is why we recommend relying on webhooks for integrating Pipe instead on relying on the JavaScript APIs. When the disconnection is a result of a browser crashing or a window being accidentally closed the JS API events will not trigger. If the disconnection is a result of a network/Internet connection problem any kind of POST or GET requests back to your server (to save the data) might fail.

Screen Recording


Pipe can capture and record the screen on Chrome 63+ using a Chrome extension we provide for you. For more information check out our Screen Recording Chrome Extension project on GitHub.

With screen recording properly configured the desktop recorder on Chrome will show the [Record Screen] button:

Record audio only


How to enable it

From the UI

You can easily enable Pipe to record audio only:

  1. Sign into your account
  2. Go to the Embed Recorder page
  3. On the left in the Options panel check Record audio only
  4. Click Generate Embed Code
  5. Copy and paste the newly generated code in your website


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 like so ao:1. Your custom object will be passed as a parameter to PipeSDK.insert()

How it looks

Once audio only recording is enabled the recorder will look as follows:

On Desktop



On Mobile


Support

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.

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 11.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%).

Audio Recording Quality

On Desktop

  • The Flash client will record audio using Nellymoser ASAO codec at 44.1 kHz in a .flv container. This is converted to AAC at 44.1 kHz in an .mp4 file.
  • The HTML5 client will record audio using Opus codec at 48 kHz in a .webm container. We convert it to AAC at 48 kHz in an .mp4 file.

On Mobile

When recording audio from mobile devices 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.

Pushing recordings to Pipe's S3 storage


By default Pipe will push the resulting .mp4 file and its associated snapshot (in case of video recordings) to our Amazon S3 buckets. Depending on the region setting (US, EU, auto) for the environment you're recording with the recording and its snapshot will be pushed to one of 2 buckets:

  • EU (Frankfurt, eu1-addpipe.s3.eu-central-1.amazonaws.com)
  • US (N. California, s3-us-west-1.amazonaws.com)

Not storing recordings on Pipe's S3 storage

Pipe gives you to the option to not store your recordings on the Pipe storage. This option is available independently for each environment and you can find it in the environment settings.

If you activate this option, Pipe will delete the original recording, the final .mp4 recording and the snapshot from our US/EU transcoding server as soon as the .mp4 recording and .jpg snapshot are pushed to all your configured storage options ((S)FTP, S3, Dropbox).

This affects only the videos recorded after the setting is on. Prior recordings won't be removed.

If you have more than one storage option configured and one of them fails, the files will be kept and another attempt to push the files to the failed storage option will be made every 2 minutes for 3 days. Once the push to all configured storage options succeeds the files will be removed from our US/EU transcoding server.

CORS headers

Both buckets we use to store recordings have CORS enabled meaning if in your GET requets you send the Origin header 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 in the browser and apply effects to it using Seriously.js.

Pushing recordings to FTP/SFTP


Configuring

Videos can be pushed to any server using FTP or SFTP after conversion. You will just need the host address and a user with writing permissions.

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.

Note: It's recommended to create a new user with writing permissions only to the folder in which you want to push the converted files.

(S)FTP Logs

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).

FTP Upload Status Types

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

SFTP Upload Status Types

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

Pushing recordings to Amazon S3


After conversion, the final .mp4 videos can be pushed to your own Amazon S3 bucket for storage and delivery. You'll need an S3 bucket and security credentials.

Creating an Amazon S3 bucket

The 1st thing you need is an S3 bucket so let's create one:

  1. First of all, create an Amazon S3 account. Go to aws.amazon.com/s3/ and press the "Sign in to the Console" button:
  2. After you log in click the "Create Bucket" button:
  3. Type in the bucket name and select the region and press the "Create" button:

Obtaining the security credentials

The converted mp4 files can be uploaded to an Amazon S3 bucket after the recording is uploaded and converted. Setting this up will require the following information:

  • Access Key ID
  • Secret Access Key
  • S3 Bucket Name
  • S3 Bucket Region

To obtain these informations, log into your Amazon AWS account.

Then go to Security Credentials in the top right menu under your name.

Press Access Keys (Access Key ID and Secret Access Key)

Click on the button

then press the link.

Your access keys will show

Configuring Pipe to push to your bucket using your credentials

After you get all the required information, go to the Amazon S3 tab in your Pipe account and paste all the info in the form.

After you click Save all new videos will 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 costum 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.

S3 Logs

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).

S3 Upload Status Types

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

Pushing recordings to Dropbox


After conversion, the final .mp4 videos can be pushed to your own Dropbox folder for storage. You'll need a Dropbox account and access token.

Creating your Dropbox application

The 1st thing you need is a Dropbox app so let's create one:

  1. First of all, sign in to your Dropbox account at dropbox.com
  2. .
  3. After you log in, go to the Developer Page and click [Create App] in the top right corner under your name:
  4. In the next page:
    • select Dropbox API
    • select App folder access
    • Name your app and click [Create App]

Obtaining the Dropbox access token

The converted mp4 files can be uploaded to your Dropbox folder after the recording is uploaded and converted. Setting this up will require the following information:

  • Dropbox Access token
  • Dropbox Folder name

After the app is created you will be redirected to the app settings page. Scroll down a bit and in the OAuth 2 section
click [Generate] for the access token.

Configuring Pipe to push to your Dropbox folder using your credentials

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 videos and snapshots will be pushed to /Apps/your app name/folder name .

After you click [Save Dropbox Credentials] all new videos will be pushed to your Dropbox folder.

Dropbox Logs

The log containing information about the latest 100 attempts to push the converted files to the Dropox folder will show the following:

ID The ID of the recording that was pushed to your Dropbox folder.
Date Date and time the push attempt was made.
Token The Access Token of your Dropbox folder.
Folder The name of the folder to which your recording and snapshot is pushed.
File(s) The name of the recording and snapshot (for video recordings).
Status The status returned by the server (errors will be displayed here if the case).

Dropbox Upload Status Types

UPLOAD_OK Upload of the file was successful
FILE_DOES_NOT_EXIST The local file of the recording on Pipe's storage is missing
FAIL This may be triggered by various Dropbox S3 errors, usually related to disk space on Dropbox or trying to upload to an unexistent folder
The given OAuth 2 access token doesn't exist or has expired This is exactly what the error says
Dropbox specifc error encoded in JSON This is very self explanatory and contains a lot of details.

Setting up webhooks


Webhooks can be used to get notified whenever a new recording is made using an embedded recorder registered with your account. Multiple webhooks can be set per account.

Setting up the link

Go to your account and click on the Webhooks tab.
To add a new webhook simply click on the Create New Webhook button. You will be taken to the webhook setup page:

Webhook types

There are 6 types of webhooks that can be sent:

  1. video_recorded: sent each time a recording is made.
  2. video_converted: sent each time a recording is converted.
  3. video_copied_pipe_s3: sent each time a recording is stored to the Pipe S3 storage.
  4. video_copied_ftp: sent each time a recording is copied to (S)FTP.
  5. video_copied_s3: sent each time a recording is copied to your Amazon S3.
  6. video_copied_dbox sent each time a recording is copied to Dropbox.

Data sent

With every webhook event a variable named payload will be POSTed to the specified URL with the application/x-www-form-urlencoded content type. The value of the payload variable will be specific for each event as follows:

payload={
	"version":"1.0",
	"event":"video_recorded",
	"data":{
		"videoName":"vs1457013120534_862",
		"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":"vs1457013120534_862",	
		"duration":7,
		"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":"video name here",	
		"size":194373,
		"checksum_md5": "md5 file hash",
		"checksum_sha1": "sha1 file hash",
		"id":"0",
		"url":"https://addpipevideos.s3.amazonaws.com/b8e2f5bfd04a93b434bd8c740bff744d/vid.mp4",
		"snapshotUrl":"https://addpipevideos.s3.amazonaws.com/b8e2f5bfd04a93b434bd8c740bff744d/vid.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":"vs1457013120534_862",
		"type":"MP4",
		"size":493534,
		"id":"123",
		"payload":"your payload data string"
	}
}
payload={
	"version":"1.0",
	"event":"video_copied_s3",
	"data":{
		"s3UploadStatus":"upload success",
		"videoName":"vs1457013120534_862",
		"type":"MP4",
		"size":493534,
		"id":"123",
		"url":"https://bucketname.s3.amazonaws.com/vs1457013120534_862.mp4",
		"snapshotUrl":"https://bucketname.s3.amazonaws.com/vs1457013120534_862.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":"vs1457013120534_862",
		"type":"MP4",
		"size":493534,
		"id":"123",
		"payload":"your payload data string"
	}
}

Handling the data

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"
	}
}

Every parameter explained

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

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). It is not sent for an audio only recording.

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. These are not sent for an audio only recording.

orientation represents the orientation of the device when the recording was made. This could be either "landscape" or "potrait". This is not sent for an audio only recording.

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

  • For thevideo_copied_pipe_s3 event, it is the full path to where the recording is located on our S3 storage.
  • For thevideo_copied_s3 event, it is the full path to where the recording is located on your S3 bucket.

snapshotUrl

  • For thevideo_copied_pipe_s3 event, it is the full path to where the snapshot is located on our S3 storage. This is not sent for an audio only recording.
  • For thevideo_copied_s3 event, it is the full path to where the snapshot is located on your S3 bucket. This is not sent for an audio only recording.

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.

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.

Logs

The Webhook log will show the latest 100 requests to send data via Webhook.

The following information is available in this table:

ID The ID of the recording that sent the request to the webhook script
Date Date and time the request was made
URL The URL to the Webhook script called
Type The event that triggered the request (for now, the script will be called only when the recording has been converted)
Data sent The data that was sent via the Webhook script
HTTP Status The status returned by the server when the webhook script is called
Response The headers and the first 100 characters returned by the webhook script

Authenticating webhooks


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 usefull 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:

  1. Create a string of the webhook's URL, exactly as your entered it in Pipe. Pipe will always sign the webhook requests with the exact URL, so any small difference will prevent the signature from validating.
  2. Append the JSON POST data received via webhook to the URL string.
  3. Hash the resulting string with HMAC-SHA1, using the webhook authentication key from your account and generate a binary signature. Pipe uses binary signatures so be careful not to generate a hexadecimal signature.
  4. Base64 encode the binary signature.
  5. Compare the generated signature with the one provided by X-Pipe-Signature HTTP header.

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 on the server side


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"}
        )

)

Custom data in webhooks



flashvar's payload property can be used to attach custom data to each recording. This can be useful if you wish to tunnel data - like user id or submission id - from your embed code all the way to your webhooks.

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.

Default embed code:

var flashvars = {qualityurl: "avq/240p.xml",accountHash:"your_account_hash",showMenu:"true", mrt:120};

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"};


The pipe-payload attribute can be used to attach custom data to each recording. This can be useful if you wish to tunnel data - like user id or submission id - from your embed code all the way to your webhooks

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.

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>

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>


You can add a property named payload to your custom JavaScript object, which can be used to attach custom data to each recording. This can be useful if you wish to tunnel data - like user id or submission id - from your embed code all the way to your webhooks

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.

Custom JavaScript object without payload property:

var YOUR_CUSTOM_OBJECT_NAME = {qualityurl: "avq/240p.xml",accountHash:"your_account_hash",showMenu:1, mrt:120};

Custom JavaScript object 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"};

Sending custom data in JSON format

The payload property can be used to send JSON as well. You have two formating options in order to send the JSON correctly:

  • enclose the JSON in quotes and write the JSON normally: payload:'{"a":"b"}'
  • enclose the JSON in double quotes and escape the double quotes from inside the JSON payload:"{\"a\":\"b\"}"

Retrieving the data

The payload data you've sent will be sent back to you with all the webhooks associated with the recording as the value of the payload name/value pair from the data object.

{
	"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"
	}
}

JavaScript Control API (Desktop)


Note: the JavaScript Control API is only available for the desktop Flash & HTML5 recorders.

The JavaScript Control API allows you to control Pipe's desktop recording clients 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.

Controlling the recorder through JavaScript when using the 1.0 embed code

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>

Full list of control methods you can use

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:

  1. onCamAccess() is called by Pipe and the value of it's 1st parameter is true
  2. onRecorderReady() (Embed Code v1.0) or onReadyToRecord() (Embed Code v2.0) is called by Pipe

If 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.

Removing the Pipe Recorder from page (Embed Code 1.0)

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.

Controlling the recorder through JavaScript when using the 2.0 embed code (HTML)

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(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.

Full list of control methods you can use

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:

  1. onCamAccess() is called by Pipe and the value of it's 1st parameter is true
  2. onRecorderReady() (Embed Code v1.0) or onReadyToRecord() (Embed Code v2.0) is called by Pipe

If 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

Controlling the recorder through JavaScript when using the 2.0 embed code (JS)

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 recroder 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(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.

Full list of control methods you can use

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:

  1. onCamAccess() is called by Pipe and the value of it's 1st parameter is true
  2. onRecorderReady() (Embed Code v1.0) or onReadyToRecord() (Embed Code v2.0) is called by Pipe

If 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

JavaScript Events API (Desktop)


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:

  • show a message, a warning or a timer in the HTML page
  • activate an input field or button in the HTML page
  • redirect the user to another page

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.

On desktop there are 2 different set of events and corresponding event functions:

Event functions executed when recording a new video from desktop

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

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 - the subdomain of the Amazon S3 region where the final video and snapshot will be stored by Pipe, for example addpipevideos.s3.amazonaws.com. The final video will be stored at https://addpipevideos.s3.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(', ')+")");
}

onCamAccess(allowed, recorderId);

Description:

onCamAccess is triggered:

  1. when clicking the Allow or Deny radio buttons in Flash Player's camera/microphone Privacy panel. The Privacy panel will be brought up by the Pipe recorder but it can also be manually brought up by the user by right clicking on the Pipe client - your code should cope with 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.
  2. automatically if the [ ] Remember checkbox was previously selected in Flash Player's Privacy panel

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 pausing Flash animations to save battery life

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:

  1. skip initial screen is on (sis:1 in the embed code)
  2. the user has only 1 webcam and 1 microphone
  3. you have previously checked [ ] Remember in FP's Privacy panel

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:

  • the user clicked the [Allow] button OR
  • clicked [Allow] + [Remember] in a previous session (in which case Flash Player's Privacy dialog box is not shown)
and false if
  • the user clicked the [Deny] button OR
  • if a user clicked [Deny] + [Remember] in a previous session (in which case Flash Player's Privacy dialog box is not shown)
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

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 was disconnected

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);

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: (connected, rejected, invalid app, closed, failed)
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 fucntion is called by the Pipe desktop client every 10th of a second (100 miliseconds) 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 - the subdomain of the Amazon S3 region where the final video will be stored by Pipe, for example addpipevideos.s3.amazonaws.com. The final video will be stored at https://addpipevideos.s3.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);

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 from HTML/JS

Chrome pausing Flash animations to save battery life

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:

  1. skip initial screen is on (sis:1 in the embed code)
  2. the user has only 1 webcam and 1 microphone

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(', ')+")");
}

Event functions when uploading an existing file from desktop

Below is the list of JavaScript functions the Pipe client will execute when the user is UPLOADING an existing video from a desktop device. 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 - the subdomain of the Amazon S3 region where the final video will be stored by Pipe, for example addpipevideos.s3.amazonaws.com. The final video will be stored at https://addpipevideos.s3.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(', ')+")");
}

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(', ')+")");
}

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.

Getting the recorder object

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(', ')+")");
    }
});

On desktop there are 2 different set of events and corresponding event functions:

Event functions when recording a new video from desktop

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(recorderId,cam_number,mic_number){
	var args = Array.prototype.slice.call(arguments);
	console.log("userHasCamMic("+args.join(', ')+")");
}

btRecordPressed(recorderId)

Description: RECORD button is pressed

Passed Parameters:
recorderId - the recorder id

Example:

myRecorderObject.btRecordPressed(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(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(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(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 - the subdomain of the Amazon S3 region where the final video and snapshot will be stored by Pipe, for example addpipevideos.s3.amazonaws.com. The final video will be stored at https://addpipevideos.s3.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(recorderId, streamName, streamDuration, audioCodec, videoCodec, fileType, audioOnly, location){
	var args = Array.prototype.slice.call(arguments);
	console.log("onUploadDone("+args.join(', ')+")");
}

onCamAccess(recorderId, allowed)

Description:

onCamAccess is triggered:

  1. when clicking the Allow or Deny radio buttons in Flash Player's camera/microphone Privacy panel. The Privacy panel will be brought up by the Pipe recorder but it can also be manually brought up by the user by right clicking on the Pipe client - your code should cope with 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.
  2. automatically if the [ ] Remember checkbox was previously selected in Flash Player's Privacy panel

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 pausing Flash animations to save battery life

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:

  1. skip initial screen is on (sis:1 in the embed code)
  2. the user has only 1 webcam and 1 microphone
  3. you have previously checked [ ] Remember in FP's Privacy panel

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:

  • the user clicked the [Allow] button OR
  • clicked [Allow] + [Remember] in a previous session (in which case Flash Player's Privacy dialog box is not shown)
and false if
  • the user clicked the [Deny] button OR
  • if a user clicked [Deny] + [Remember] in a previous session (in which case Flash Player's Privacy dialog box is not shown)

Example:

myRecorderObject.onCamAccess(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(recorderId){
	var args = Array.prototype.slice.call(arguments);
	console.log("onPlaybackComplete("+args.join(', ')+")");
}

onRecordingStarted(recorderId)

Description: the Pipe desktop client started recording

Passed Parameters:
recorderId - the recorder id

Example:

myRecorderObject.onRecordingStarted(recorderId){
	var args = Array.prototype.slice.call(arguments);
	console.log("onRecordingStarted("+args.join(', ')+")");
}

onConnectionClosed(recorderId)

Description: the connection to the media server was disconnected

Passed Parameters:
recorderId - the recorder id

Example:

myRecorderObject.onConnectionClosed(recorderId){
	var args = Array.prototype.slice.call(arguments);
	console.log("onConnectionClosed("+args.join(', ')+")");
}

onFPSChange(recorderId,currentFPS)

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(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:
recorderId - the recorder id status - the actual connection status: (connected, rejected, invalid app, closed, failed)

Example:

myRecorderObject.onConnectionStatus(recorderId, status){
	var args = Array.prototype.slice.call(arguments);
	console.log("onConnectionStatus("+args.join(', ')+")");
}

onMicActivityLevel(recorderId, currentActivityLevel)

Description: the fucntion is called by the Pipe desktop client every 10th of a second (100 miliseconds) 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(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 - the subdomain of the Amazon S3 region where the final video will be stored by Pipe, for example addpipevideos.s3.amazonaws.com. The final video will be stored at https://addpipevideos.s3.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(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)

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 from HTML/JS

Chrome pausing Flash animations to save battery life

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:

  1. skip initial screen is on (sis:1 in the embed code)
  2. the user has only 1 webcam and 1 microphone

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(recorderId){
	var args = Array.prototype.slice.call(arguments);
	console.log("onFlashReady("+args.join(', ')+")");
}

Event functions when uploading an existing file from desktop

Below is the list of JavaScript events that the Pipe client will dispatch when the user is UPLOADING an existing video from a desktop device. 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(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 - the subdomain of the Amazon S3 region where the final video will be stored by Pipe, for example addpipevideos.s3.amazonaws.com. The final video will be stored at https://addpipevideos.s3.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(recorderId, filename,filetype,videoId,audioOnly,location){
	var args = Array.prototype.slice.call(arguments);
	console.log("onDesktopVideoUploadSuccess("+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(recorderId, error){
	var args = Array.prototype.slice.call(arguments);
	console.log("onDesktopVideoUploadFailed("+args.join(', ')+")");
}

JavaScript Events API (Mobile)


Every time something happens with the mobile recording client (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 event functions to your HTML/JS app and extend them with your own code to do your bidding.

When using the v1 embed code you can just add these JS event functions to your HTML page. The Pipe mobile recording 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 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 - the subdomain of the Amazon S3 region where the final video will be stored by Pipe, for example addpipevideos.s3.amazonaws.com. The final video will be stored at https://addpipevideos.s3.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(', ')+")");
}

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(', ')+")");
}

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.

Getting the recorder object

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("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 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("btRecordPressed("+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(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 - the subdomain of the Amazon S3 region where the final video will be stored by Pipe, for example addpipevideos.s3.amazonaws.com. The final video will be stored at https://addpipevideos.s3.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(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(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(recorderId, error){
	var args = Array.prototype.slice.call(arguments);
	console.log("onVideoUploadFailed("+args.join(', ')+")");
}

REST API


The REST API allows any user with an addpipe.com account to request information from our servers programmatically and in a standardized manner, using JSON.

All requests are made against https://api.addpipe.com.

Using the API Key

The API Key can be found in your Pipe account settings and it should be kept in a safe place, like any other password. If compromised, a new API key can be generated.

Authentication will be made with the custom header X-PIPE-AUTH, followed by your Api Key.

API endpoints

/video

Perform actions on active videos from your account.

    Parameters
  • all, optional. May be included or omitted from the request.

Requests available:
  • GET https://api.addpipe.com/video/all - get all videos from your account. JSON response
/video/:id

Perform actions for a specific video.

    Parameters:
  • :id - numerical representation of the video ID which can be found in your AddPipe account, under the Recorded Videos tab.

Requests available:
  • GET https://api.addpipe.com/video/167895864 - get specific information for this recording id JSON response
  • DELETE https://api.addpipe.com/video/167841 - deletes the recording with this id
/account

Perform actions on your account.


Requests available:
  • GET https://api.addpipe.com/account - get information regarding your AddPipe.com account JSON response
  • PUT https://api.addpipe.com/account - update your account information following the below JSON scheme
For PUT requests, make sure you send at least one of the following:
{
  "subscribed": "1"
}                       
/environment

Access environment related information.


Requests available:
  • GET https://api.addpipe.com/environment - get information regarding your AddPipe.com environments JSON response
/environment/:id

Get details about a specific environment.

    Parameters:
  • :id - numerical representation of the environment unique ID which can be retrieved by using the GET /environment endpoint

Requests available:
  • GET https://api.addpipe.com/environment/1537 - get specific information for this environment id JSON response
/webhook

Access webhook related information.


Requests available:
  • GET https://api.addpipe.com/webhook - get information regarding your Webhooks JSON response
/webhook/:id

Perform actions for a specific webhook.

    Parameters:
  • :id - numerical representation of the webhook ID which can be retrieved by using the GET /webhook endpoint.

Requests available:
  • PUT https://api.addpipe.com/webhook/69 - update your webhook by following the below JSON scheme
For PUT requests, make sure you send at least one of the following:
{	
  "webhook": "http://your-fancy-website.com/webhook",
  "webhook_recorded": "0",
  "webhook_transcoded": "1",
  "webhook_copied_s3": "0",
  "webhook_copied_ftp": "0",
  "webhook_copied_dbox": "0",
  "env_id":"2"
}                           
/amazon

Perform actions on your Amazon related information stored with AddPipe.


Requests available:
  • GET https://api.addpipe.com/amazon - get information regarding your Amazon credentials JSON response
/amazon/:id

Perform actions for a specific Amazon S3 credentials set.

    Parameters:
  • :id - numerical representation of the Amazon S3 credentials ID which can be retrieved by using the GET /amazon endpoint.

Requests available:
  • PUT https://api.addpipe.com/amazon/69 - update your Amazon credentials following the below JSON scheme
For PUT requests, make sure you send at least one of the following:
{
  "amz_key": "YourAmazonKey",
  "amz_secret": "YourAmazonSecret",
  "amz_bucket": "TheBucket",
  "amz_bucket_region": "AndTheRegion",
  "env_id": "1"
}                       
/ftp

Perform actions on your FTP/SFTP related information stored with AddPipe.


Requests available:
  • 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.

    Parameters:
  • :id - numerical representation of the (S)FTP credentials ID which can be retrieved by using the GET /ftp endpoint.

Requests available:
  • PUT https://api.addpipe.com/ftp/69 - update your (S)FTP credentials following the below JSON scheme
For PUT requests, make sure you send at least one of the following:
{
  "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",
  "env_id": "1"
}                       
/dropbox

Perform actions on your Dropbox related information stored with AddPipe.


Requests available:
  • GET https://api.addpipe.com/dropbox - get information regarding your Dropbox credentials JSON response
/dropbox/:id

Perform actions for a specific Dropbox credentials set.

    Parameters:
  • :id - numerical representation of the Dropbox credentials ID which can be retrieved by using the GET /dropbox endpoint.

Requests available:
  • PUT https://api.addpipe.com/dropbox/69 - update your Dropbox credentials following the below JSON scheme
For PUT requests, make sure you send at least one of the following:
{
  "dbox_token": "YourDropboxToken",
  "dbox_folder": "YourDropboxFolder",
  "env_id": "1"
}                       

Code Examples

PHP


$client = new http\Client;
$request = new http\Client\Request;

$body = new http\Message\Body;
$body->append('{
  "amz_key": "",
  "amz_secret": "",
  "amz_bucket": "",
  "amz_bucket_region": ""
  "env_id": "1"
}');

$request->setRequestUrl('https://api.addpipe.com/amazon');
$request->setRequestMethod('PUT');
$request->setBody($body);

$request->setHeaders(array(
  'cache-control' => 'no-cache',
  'content-type' => 'application/json',
  'x-pipe-auth' => 'your-Pipe-Api-Key'
));

$client->enqueue($request)->send();
$response = $client->getResponse();

echo $response->getBody();

cURL


curl -X PUT -H "X-PIPE-AUTH: Your-Pipe-Api-Key" -H "Content-Type: application/json" -H "Cache-Control: no-cache" -H -d '{
  "amz_key": "",
  "amz_secret": "",
  "amz_bucket": "",
  "amz_bucket_region": "",
  "env_id": "1"
}' 'https://api.addpipe.com/amazon'

JavaScript


var data = JSON.stringify({
  "amz_key": "",
  "amz_secret": "",
  "amz_bucket": "",
  "amz_bucket_region": ""
  "env_id": "1"
});

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);

Go


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  \"env_id\": \"1\"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))

}

Python


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  \"env_id\": \"1\"\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"))

Ruby


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  \"env_id\": \"1\"\n}"

response = http.request(request)
puts response.read_body

Bash (wget)


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  "env_id": "1"\n}' \
  --output-document \
  - https://api.addpipe.com/amazon

Bash (cURL)


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  "env_id": "1"\n}'