Introduction
Using this application, you can upload video in any format (.mov, .avi, .wav, flv). If you do not upload video file in flv format, then this will be converted to flv file using ffmpeg for progressive streaming. ASP.NET handler is used for pseudo-streaming and flowplayer is used to show flv files. You can also play MPEG-4 H.264 (.mp4) formatted file using flawplayer. I will discuss about progressive streaming of .mp4 also here.
Implementation
In my previous blog here, you can see the implementation of an ASP.NET handler for uploading file using valums ajax upload and I am using this file upload handler for uploading video and audio files. As flv is the best format for website, so video file is converted to flv format after upload.
Uploading Video File And Convert to Flash Video (flv) Format
In my previous article, I have shown how can I upload image file using valum's ajax upload using ASP.NET handler. I am using the same valum’s upload control for uploading video/audio file. This supports multiple upload by default but you can set params to upload single files only by setting parameter multiple:false.
Also I have given restriction in allowed extensions.
var uploader = new qq.FileUploader({
element: document.getElementById('file-uploader-demo1'),
action: 'FileUpload.ashx',
template: '<div class="qq-uploader">' +
'<div class="qq-upload-drop-area"><span>Drop files here to upload
</span></div>' +
'<div class="qq-upload-button">Upload a video</div>' +
'<ul class="qq-upload-list"></ul>' +
'</div>',
multiple: false,
allowedExtensions: ['flv', 'mov', 'mp4', 'avi', '3gp', 'mgp', 'wmv'],
debug: true,
onComplete: function (id, fileName, responseJSON) {
if (responseJSON.success)
$("#videoContainer").append("<div class='player'
style='display:block;width:400px;height:400px;
background-image:url(" + responseJSON.image + ");
' href='" + responseJSON.path + "'>
<img src='images/play_large.png' alt='Play this video' />
</div>");
flowplayer("div.player", "Scripts/flowplayer/flowplayer-3.2.7.swf", {
clip: {
autoPlay: false,
autoBuffering: true
}
});
}
});
In the above code snippet, valum’s upload options are changed to support single upload and only video files. I have also changed template of upload button. I will discuss OnComplete
code later.
As user is watching progressive stream of flv files so when user is uploading a flv file, then only thumbnail is created from that file. But when user uploads other formatted file like .mov, avi, mpeg or .wav, then video file is converted to flv format. FFMPEG is a very lovely tool for converting video file. Using this tool, you can extract audio from video and also can generate thumbnail from video file specific frame.
I am not familiar with ffmpeg command arguments so I used standard options for Flash Video (flv). The format I have got from WinFF is:
"ffmpeg.exe" -i "sample.avi" -vcodec flv -f flv -r 29.97
-s 320x240 -aspect 4:3 -b 300k -g 160 -cmp dct -subcmp dct
-mbd 2 -flags +aic+cbp+mv0+mv4 -trellis 1 -ac 1 -ar 22050 -ab 56k "sample.flv"
Using this code snippet, I have converted my 25MB .wav file to 1.4M flv file. You will not able to run ffmpeg command using ASP.NET basic authentication. So for running “ffmpeg.exe”, you need to impersonate to specific user account. Here, you can see how to impersonate a specific user in code.
if (Path.GetExtension(phyicalFilePath).Equals(".flv")) return phyicalFilePath;
if (AuthenticationHelper.ImpersonateValidUser("user", ".", "*******"))
{
var argument = string.Format("-i {0} -vcodec flv -f flv -r 29.97
-s 320x240 -aspect 4:3 -b 300k -g 160 -cmp dct -subcmp dct
-mbd 2 -flags +aic+cbp+mv0+mv4 -trellis 1 -ac 1 -ar 22050
-ab 56k {1}", phyicalFilePath,
Path.ChangeExtension(phyicalFilePath, "flv"));
-vcodec libx264 -acodec libfaac -ar 48000 -ab 128k
-coder 1 -flags +loop -cmp +chroma -partitions
+parti4x4+partp8x8+partb8x8 -me_method hex -subq 6 -me_range 16
-g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71
-b_strategy 1 -threads 0 {1}", phyicalFilePath,
Path.ChangeExtension(phyicalFilePath, "mp4"));
ProcessStartInfo process = new ProcessStartInfo
(ffmpegPhysicalPath, argument);
Process proc = new Process();
proc.StartInfo = process;
proc.Start();
proc.WaitForExit();
AuthenticationHelper.UndoImpersonation();
return Path.ChangeExtension(phyicalFilePath, "flv");
Here you can see command for converting video file into flash video (flv) format. When you will use my code, you have to set ffmpegPhysicalPath
field variable with the physical path of ffmpeg.exe file.
You can send the flv file path to client when flv conversion is completed and flowplayer will ask ASP.NET handler for streaming the video. But I also want to show a thumbnail splash image so that user can understand that video is uploaded. And on clicking splash image, ASP.NET handler will be called and user can see video using flawplayer.
Generating thumbnail image from video file is very easy using ffmpeg. In flawplayer forum, you can see the details about generating thumbnail from video http://flowplayer.org/tutorials/generating-thumbs.html.
After completing these steps, I have sent a JSON response to containing flv location and image location.
var flvpath = ConvertToFLV(phyicalFilePath);
var tumbnail = CreateThumbnail(phyicalFilePath);
context.Response.Write("{success:true, name:\"" +
filename + "\", path:\"" + path + "/" +
Path.GetFileName(flvpath) + "\", image:\"" +
path + "/" + Path.GetFileName(tumbnail) + "\"}");
Uploading Large File
You might fail to upload large files as by default IIS supported content length is 30000000 Byte.

You also need to set maxRequestLength
in webconfig otherwise you will get an exception while fetching large file. Suppose that I support maximum 2G size file in my site. My web.config settings are:
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpRuntime maxRequestLength="4124672" requestValidationMode="2.0" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="4223664128"></requestLimits>
</requestFiltering>
</security>
<handlers>
<add name="MP3Streaming" path="*.mp3" verb="*" type="MP3Streaming"
resourceType="Unspecified" preCondition="integratedMode" />
<add name="flvStreaming" path="*.flv" verb="*" type="FLVStreaming"
resourceType="Unspecified" preCondition="integratedMode" />
</handlers>
</system.webServer>
Here maxRequestLength
is in KB and maxAllowedContentLength
in Byte format. Now you can upload maximum 2G file using Valums upload control.
Watching Progressive Streaming Video using ASP.NET Handler
Flowplayer forum http://flowplayer.org/forum/5/14702#post-14702 discussed steps to implement progressive streaming using ASP.NET handler very well so for IIS settings you can read there. I have just made copy paste and used same code in my handler. So when flowplayer request to server to get flv file, then FLVStreaming
handler will be called which will provide flv file progressively.
You can download flowplayer swf file from FlowPlayer site. As thumbnail of video and flv location is sent after uploading using valums control. So here OnComplete
function code is:
onComplete: function (id, fileName, responseJSON) {
if (responseJSON.success)
$("#videoContainer").append("<div class='player'
style='display:block;width:400px;height:400px;
background-image:url(" + responseJSON.image + ");
' href='" + responseJSON.path + "'>
<img src='images/play_large.png' alt='Play this video' />
</div>");
flowplayer("div.player",
"Scripts/flowplayer/flowplayer-3.2.7.swf", {
clip: {
autoPlay: false,
autoBuffering: true
}
});
}
});
You can see here thumbnail image is set as background and a play image displayed in middle. After clicking on the image, flowplayer script will be called and request for flv file to server and then FLVStreaming
handler will be called.

Streaming MP4 Video
FlowPlayer also support H.264 mp4 video format. You can also use JW Player.
Converting Video File into mp4 Formatted Video File
ffmpeg command for converting video file into h264 mp4 formatted video file is:
var argument = string.Format("-i {0} -crf 35.0 -vcodec libx264
-acodec libfaac -ar 48000 -ab 128k -coder 1 -flags +loop
-cmp +chroma -partitions +parti4x4+partp8x8+partb8x8
-me_method hex -subq 6 -me_range 16 -g 250 -keyint_min 25
-sc_threshold 40 -i_qfactor 0.71 -b_strategy 1 -threads 0 {1}",
phyicalFilePath, Path.ChangeExtension(phyicalFilePath, "mp4"));
The implementation of handler for mp4 can be found here. You can see there client type is different for mp4. You can also use JW Player. But I do not want to mix two implementations here, so I did not provide mp4 handler here.
Streaming MP3 Audio
Then handler for MP3 audio is the same as flv player but just content-type
is different.
context.Response.AppendHeader("Content-Type", "audio/mp3");
context.Response.AppendHeader("Content-Length", fs.Length.ToString());
Flowplayer also supports mp3 file. We can change configuration of FlowPlayer
using the following script:
var uploader = new qq.FileUploader({
element: document.getElementById('file-uploader-demo2'),
action: 'AudioUpload.ashx',
multiple: false,
template: '<div class="qq-uploader">' +
'<div class="qq-upload-drop-area"><span>Drop files here to upload
</span></div>' +
'<div class="qq-upload-button">Upload a mp3</div>' +
'<ul style="display:none" class="qq-upload-list"></ul>' +
'</div>',
allowedExtensions: ['mp3'],
debug: true,
onComplete: function (id, fileName, responseJSON) {
if (responseJSON.success)
$("#audioContainer").append("<a id='audioPlayer'
style='display:block;height:30px;' href='" + responseJSON.path + "'/>");
$f("audioPlayer", "Scripts/flowplayer/flowplayer-3.2.7.swf", {
plugins: {
controls: {
fullscreen: false,
height: 30,
autoHide: false
}
},
clip: {
autoPlay: false,
onBeforeBegin: function () {
$f("player").close();
}
}
});
}
});
After upload is complete, the flowplayer will be displayed like this. And clicking on play button, it will call MP3Streaming handler and run mp3 in progressing manner.