Platform documentation & tutorials
Integrate Panda with your web app
- Full Guides
- Integration
- Profiles
- Downloads
- More...
Panda uploader
Panda uploader allows you to upload videos from your applications to Panda. It uses an HTML5-based upload method or, if this is not supported, falls back to a Flash-based solution.

It works as a jQuery plugin, and requires requires JQuery version 1.3.
Link to the Javascript
Include the following declaration in your page, after loading jQuery.
<script src="http://cdn.pandastream.com/u/1.4/jquery.panda-uploader.min.js" type="text/javascript"></script>
Or if you intend to use SSL.
<script src="//d21qbsp9m249bi.cloudfront.net/u/1.4/jquery.panda-uploader.min.js" type="text/javascript"></script>
The above will load the necessary JavaScript code.
Generating access details
You will also need a the help of a server-side library to generate access details for you. On the examples below, you will notice the following snippet of JS code:
var panda_access_details = {
'access_key': 'your-access-key',
'cloud_id': 'your-cloud-id',
'timestamp': '2010-02-02T17:04:46+00:00',
'signature': 'dC/M34sNc7v+oyhFRfVLEKpkVMNyhhyuyCECAQiR6nrUw='
};
These access details are best generated by a support library. We recommend you use the ones we provide for several popular server-side languages: Ruby, PHP and Python.
For either of the above libraries, the process is the same: initialise a Panda instance and use the method signed_params() to generate your access details:
# Ruby example
ruby_access_details = Panda.signed_params('POST', '/videos.json')
# PHP example
$php_access_details = $panda->signed_params('POST', '/videos.json');
# Python example
python_access_details = panda.signed_params('POST', '/videos.json')
Then convert the returned details to JSON and add them to your HTML template.
Simplest example
The following is the simplest working form that will upload a video:
<form action="/path/to/action">
<!-- the control will appear next to this, and the video ID will be stored here after the upload -->
<input type="hidden" name="panda_video_id" id="returned_video_id" />
<!-- a submit button -->
<input type="submit" value="Upload video" />
</form>
<script>
var panda_access_details = {
'access_key': 'your-access-key',
'cloud_id': 'your-cloud-id',
'timestamp': '2010-02-02T17:04:46+00:00',
'signature': 'dC/M34sNc7v+oyhFRfVLEKpkVMNyhhyuyCECAQiR6nrUw='
};
jQuery("#returned_video_id").pandaUploader(panda_access_details, {
// Uncomment the line below if your account is in the EU
// api_host: 'api-eu.pandastream.com'
});
</script>
This will render a fairly ugly form. We’ll worry about the looks later. For now:
- Click on “Choose file”. You will be shown a file selection dialog.
- Select a file to upload.
- Click “Upload video” and the upload will start.
After the upload, Panda returns a unique ID that identifies your video. This will be automatically set as the value of the hidden field #returned_video_id, which was specified in the jQuery call. Then, the form will be finally submitted so your application can read this value and use it to reference the video later.
Adding a progress bar
The example above is minimal, and has a very poor interface. At the moment, the user doesn’t know how the upload process is going, or if it is working at all. A progress bar would be very appropriate here, and one is included by default.
To enable it, first create a DIV that will contain the bar:
<!-- upload progress bar (optional) -->
<div id="upload_progress" class="panda_upload_progress"></div>
And then let pandaUploader() know about it:
jQuery("#returned_video_id").pandaUploader(panda_access_details, { upload_progress_id: 'upload_progress' });
Finally, the full example with all the controls would be:
<form action="/player.php">
<!-- the control will appear next to this, and the video ID will be stored here after the upload -->
<input type="hidden" name="panda_video_id" id="returned_video_id" />
<!-- upload progress bar (optional) -->
<div id="upload_progress" class="panda_upload_progress"></div>
<!-- a submit button -->
<p><input type="submit" value="Upload video" /></p>
<script>
var panda_access_details = {
'access_key': 'your-access-key',
'cloud_id': 'your-cloud-id',
'timestamp': '2010-02-02T17:04:46+00:00',
'signature': 'dC/M34sNc7v+oyhFRfVLEKpkVMNyhhyuyCECAQiR6nrUw='
};
jQuery("#returned_video_id").pandaUploader(panda_access_details, {
// Uncomment the line below if your account is in the EU
// api_host: 'api-eu.pandastream.com',
upload_progress_id: 'upload_progress' // Optional
});
</script>
</form>
Advanced usage
Additional arguments
At the moment, the following arguments are supported:
upload_progress_id: the ID of DIV that will contain the progress bar.api_host: alternative host for the Panda API. Must be set toapi-eu.pandastream.comif you signed up for the EU region.uploader_dir: path were the uploader files are located in the web server. By default ”/panda_uploader”upload_strategy: see below.widget: force use of HTML5-based or Flash-based widget. By default, HTML5 widget is used if supported, falling back to Flash if not. See below.allowed_extensions: an array of strings. These are the file extensions that will be allowed by the uploader. See below.file_size_limit: maximum size of the files to upload. By default, units are expected to be Kilobytes. Other units can be specified by passing a string such as “25MB” or “1GB”. Valid units are B, KB, MB and GB.- and several events:
onwidgetload,onchange,onprogress,onreadystatechange,onsuccess,onload,onerror. See below.
Upload strategies
This plugin allows for two “strategies” to upload the video file:
- Upload on submit: the file will be uploaded when the form is submitted.
- Upload on select: the file will be uploaded as soon as it is selected.
The default behaviour is upload on submit. If you wish to upload on select instead, you’ll need to specify this explicitly:
jQuery("#returned_video_id").pandaUploader(panda_access_details, {
upload_strategy: new PandaUploader.UploadOnSelect()
});
Upload on submit
The “upload on submit” strategy also accepts an option:
disable_submit_button: defaults to true. When true, it will disable the form’s submit button until a video is selected.
To specify strategy options, do the following:
jQuery("#returned_video_id").pandaUploader(panda_access_details, {
upload_strategy: new PandaUploader.UploadOnSubmit({
disable_submit_button: false
})
});
Upload on select
When using the “upload on select” strategy, you have to bear this in mind: users may upload a file, then change their minds about it and upload another one in its place. If you want this to work correctly, you have to make sure that each separate upload uses a different cryptographic signature.
How to generate another signature?:
- You should make an Ajax request to your own site to generate the signature
- The
panda_access_detailsparameter should be given as a function rather than a hash, so that this is regenerated for every upload
Have a look at some example code. On it, the important bits are:
pandaUploaderis passed a functionget_signed_paramsget_signed_paramsreturns the params and the signature and starts an AJAX request to get new ones
I hope that helps…
Widgets
Smart widget (HTML5 + Flash fallback)
This is the default widget. It checks if the browser supports Flash-less uploads using HTML5 features (supported in Gecko and Webkit browsers). If this is not the case, a Flash solution is used.
Only if you want the HTML5 widget to be the default choice, but still want to be able to pass options to the Flash widget, do as the following:
var html5_options = {}; // None available just yet
var flash_options = { button_image_url : "/my-cool-button.png" };
jQuery("#returned_video_id").pandaUploader(panda_access_details, {
widget: new PandaUploader.SmartWidget(html5_options, flash_options)
});
Flash widget
By default, the plugin checks if the browser supports Flash-less uploads using HTML5 features (supported in Gecko and Webkit browsers). If this is not the case, a Flash solution is used.
If you instead want to use Flash in all cases, you may specify so by using the widget option:
jQuery("#returned_video_id").pandaUploader(panda_access_details, {
widget: new PandaUploader.FlashWidget()
});
The constructor of the widget accepts an argument: a hash of options to be passed on to swfupload. For example, if you want to show a different button, do:
jQuery("#returned_video_id").pandaUploader(panda_access_details, {
widget: new PandaUploader.FlashWidget({
button_image_url : "/my-cool-button.png",
button_width : 70,
button_height : 30
})
});
All available arguments are documented at the SWFUpload site.
In addition to SWFUpload options, the Flash widget accepts one additional argument:
add_filename_field: add a text field next to the widget. This will show the name of the currently selected file, mimicking the behaviour of a standard HTML file field. Defaults totrue.
Allowed extensions
The setting allowed_extensions tells the uploader what file extensions are acceptable. By default, many common file exceptions are accepted, but you may tweak this list.
If you don’t want any limitation, set it to null:
$('#returned_video_id').pandaUploader(panda_access_details, {
allowed_extensions: null
});
If you wish to customize the list of allowed file extensions, put them in an array like follows:
$('#returned_video_id').pandaUploader(panda_access_details, {
allowed_extensions: ['mp4', 'wmv', 'mkv']
});
Custom events
This plugin also provides a number of events where you can plug your own actions:
onwidgetload: widget has been initialised and rendered on the pageonchange: a new file has been selectedonprogress:: called multiple times when the file is being uploadedonreadystatechange: called when the server responds to preflight (see W3C spec) and upload requests. Please note: this is only available with the HTML5 widget.onsubmit: submit event has been trigger. Return false to abort the upload.onload: file upload completed (successfully or not). Results are not yet available.onsuccess: operation completed successfullyonerror: the upload finished with an error
Example:
$('#returned_video_id').pandaUploader(panda_access_details, {
onchange: function() {
alert("New file selected");
},
});
Styling up the HTML5 widget
If you want to change the style of the HTML5 widget, we recommend the following article: http://www.quirksmode.org/dom/inputfile.html
Aborting uploads
If you want to abort an upload that is currently taking place, use the abort() function of the widget:
// Create the widget separately
var widget = new PandaUploader.SmartWidget();
// Initialize the uploader
$('#returned_video_id').pandaUploader(<%= Panda.signed_params("POST", "/videos.json").to_json %>, {
widget: widget,
onabort: function(){ alert("onabort was called!"); }
});
// Attaching to example cancel button
$('#cancel_button').click(function() {
// Actually aborting the upload
widget.abort();
});
Change the S3 Bucket path
If you want to store your files to a different path on S3, only thing you need to do is add the path_format attribute while signing the request.
# Ruby example
ruby_access_details = Panda.signed_params('POST', '/videos.json', {:path_format => 'my-s3-folder/:id'})
# PHP example
$php_access_details = $panda->signed_params('POST', '/videos.json', array('path_format' => 'my-s3-folder/:id'));
# Python example
python_access_details = panda.signed_params('POST', '/videos.json', {'path_format': 'my-s3-folder/:id'})