C# 在 ASP.NET 中上传流和播放视频
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2228208/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Upload stream and play video in ASP.NET
提问by Radhi
I have to make an interface to upload large videos up to 30MB then stream and convert it into FLV format and then play it in a browser... this is required on my site in the "Video Gallery" module. My web application is in C# and ASP.NET. I can also use jQuery.
我必须制作一个界面来上传高达 30MB 的大视频,然后流式传输并将其转换为 FLV 格式,然后在浏览器中播放......这是我网站上“视频库”模块所必需的。我的 Web 应用程序使用 C# 和 ASP.NET。我也可以使用 jQuery。
I have to send the video file in chunks then merge it at the server, stream it, create thumbnail for the video and then play it.
我必须分块发送视频文件,然后在服务器上将其合并,流式传输,为视频创建缩略图,然后播放。
Please provide me solution if anybody has.
如果有人有,请为我提供解决方案。
I found some code but it is all in PHP. I haven't found any C#, ASP.NET code.
我找到了一些代码,但都是用 PHP 编写的。我还没有找到任何 C#、ASP.NET 代码。
Finally I got the code to upload the video file in chunks... but please help me to do further processes, like create its thumbnail and display the video in a browser.
最后我得到了分块上传视频文件的代码......但是请帮助我做进一步的处理,比如创建它的缩略图并在浏览器中显示视频。
Here is code to upload the video in chunks.
这是分块上传视频的代码。
Upload button click
点击上传按钮
protected void btnUploadVideo_Click(object sender, EventArgs e)
{
UploadVideoFile obj = new UploadVideoFile();
string FileName = fuUploadVideo.FileName;
string DestPath = Server.MapPath("Videos");
string strFinalFileName = Path.GetFileName(fuUploadVideo.FileName);
long FileLength = fuUploadVideo.PostedFile.ContentLength;
long uploadchunklimit;
int SizeLimit = (int)FileLength;
if (FileLength <= 1024)
{
uploadchunklimit = 1;
SizeLimit = (int)FileLength;
}
else if (FileLength > 10240)
{
uploadchunklimit = FileLength / 10240;
SizeLimit = 10;
}
else if (FileLength <= 10240 && FileLength > 1024)
{
uploadchunklimit = FileLength / 1024;
}
else
{
uploadchunklimit = FileLength / 1024;
}
long lngSize = (long)SizeLimit;
lngSize *= 1024 * 1024;
string ext = Path.GetExtension(fuUploadVideo.PostedFile.FileName);
string strDestFileName = Server.MapPath("videofile") + "\" + Guid.NewGuid() + ext;
string strSrcFile = Server.MapPath("videofile/" + Path.GetFileName(strDestFileName));
string strDestFile = Server.MapPath("mergefile") + "//" + Path.GetFileName(strDestFileName);
string strFinalDest = Server.MapPath("FinalFile") ;
obj.Process(fuUploadVideo.PostedFile.FileName, strDestFileName, lngSize, fuUploadVideo.PostedFile);
obj.MergerProcess(strSrcFile, strDestFile, strFinalDest);
}
UploadVideofile.cs
上传视频文件.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Web;
//using ContestBLL;
/// <summary>
/// This Class contains methods for upload chunks
/// </summary>
public class UploadVideoFile
{
/// <summary>
/// declaration of private members
/// </summary>
private FileStream fSIn, fSout;
/// <summary>
/// declaration of private members
/// </summary>
private int preDefinedCacheSize;
/// <summary>
/// Initializes a new instance of the Chunk class.
/// </summary>
public UploadChunk()
{
//// TODO: Add constructor logic here
}
/// <summary>
/// This method used to merge file
/// </summary>
/// <param name="strSrcPath">Source path of file</param>
/// <param name="strDestPath">destination path of file</param>
/// <param name="strFilnalDest">Final destination path of file</param>
public string MergerProcess(string strSrcPath, string strDestPath, string strFilnalDest)
{
try
{
string[] strFiles = Directory.GetFiles(strSrcPath, "*.part");
this.fSout = new FileStream(strDestPath, FileMode.Create);
BinaryWriter wFSOut = new BinaryWriter(this.fSout);
long fileSizes = 0;
fileSizes = this.GetSizes(strFiles);
foreach (string a in strFiles)
{
this.preDefinedCacheSize = this.DefineCache();
this.fSIn = new FileStream(strSrcPath + "\" + this.FileName(a), FileMode.Open);
BinaryReader rFSIn = new BinaryReader(this.fSIn);
if (this.preDefinedCacheSize > this.fSIn.Length - this.fSIn.Position)
{
this.preDefinedCacheSize = (int)this.fSIn.Length - (int)this.fSIn.Position;
}
byte[] buffer = new byte[this.preDefinedCacheSize];
while (this.fSIn.Position != this.fSIn.Length)
{
rFSIn.Read(buffer, 0, this.preDefinedCacheSize);
wFSOut.Write(buffer);
Thread.Sleep(1);
}
rFSIn.Close();
this.fSIn.Close();
}
wFSOut.Close();
this.fSout.Close();
string strFolderToDelete = strSrcPath;
if (Directory.Exists(strFolderToDelete))
{
Directory.Delete(strFolderToDelete, true);
}
if (File.Exists(strDestPath))
{
File.Copy(strDestPath, strFilnalDest + "//" + Path.GetFileName(strDestPath), false);
File.Delete(strDestPath);
}
return Path.GetFileName(strDestPath);
}
catch (Exception ex)
{
object[] customval = new object[0];
//AppError.ErrorMsg(ex.StackTrace, "UploadChunk.cs", "MergerProcess", customval);
}
}
/// <summary>
/// this method is used to ...
/// </summary>
/// <param name="strSrcPath"> path of the source file</param>
/// <param name="strDestPath">destination path of file</param>
/// <param name="lngFileSize"> Size of file to be split</param>
/// <param name="fsi">object of HttpPostedFile class</param>
public void Process(string strSrcPath, string strDestPath, long lngFileSize, System.Web.HttpPostedFile fsi)
{
string strDirectory = string.Empty, strNewFileNames = string.Empty;
long fileSize = 0;
int intCounter = 0;
try
{
//// Code to Check whether it is logical or not to Continue...
////FSIn = new FileStream(strSrcPath, FileMode.Open);
////BinaryReader rFSIn = new BinaryReader(FSIn);
BinaryReader rFSIn = new BinaryReader(fsi.InputStream);
////FileSize = FSIn.Length;
fileSize = fsi.ContentLength;
strDirectory = strDestPath;
////split it to parts in a folder Called "FileName"
System.IO.Directory.CreateDirectory(strDirectory);
////begin writing
////while (FSIn.Position != FSIn.Length)
while (rFSIn.BaseStream.Position != fsi.ContentLength)
{
this.preDefinedCacheSize = this.DefineCache();
byte[] buffer = new byte[this.preDefinedCacheSize];
strNewFileNames = strDirectory + "\" + intCounter.ToString() + ".part";
this.fSout = new FileStream(strNewFileNames, FileMode.Create);
BinaryWriter wFSOut = new BinaryWriter(this.fSout);
////while ((FSout.Position < lngFileSize) && (FSIn.Position != FSIn.Length))
while ((this.fSout.Position < lngFileSize) && (rFSIn.BaseStream.Position != fsi.ContentLength))
{
////if (((FSIn.Length - FSIn.Position) < Math.Min(PreDefinedCacheSize, (int)lngFileSize)) && (PreDefinedCacheSize > lngFileSize))
if (((fsi.ContentLength - rFSIn.BaseStream.Position) < Math.Min(this.preDefinedCacheSize, (int)lngFileSize)) && (this.preDefinedCacheSize > lngFileSize))
{
this.preDefinedCacheSize = (int)fsi.ContentLength - (int)rFSIn.BaseStream.Position;
rFSIn.Read(buffer, 0, this.preDefinedCacheSize);
wFSOut.Write(buffer);
Thread.Sleep(1);
}
else
{
if (this.preDefinedCacheSize > lngFileSize)
{
this.preDefinedCacheSize = (int)lngFileSize;
}
rFSIn.Read(buffer, 0, this.preDefinedCacheSize);
wFSOut.Write(buffer);
Thread.Sleep(1);
}
}
wFSOut.Close();
this.fSout.Close();
intCounter++;
}
////finish
rFSIn.Close();
}
catch (Exception ex)
{
object[] customval = new object[0];
//AppError.ErrorMsg(ex.StackTrace, "UploadChunk.cs", "Process", customval);
}
}
/// <summary>
/// this i sused to define cache
/// </summary>
/// <returns>return integer value</returns>
private int DefineCache()
{
return 8192 * 2;
}
/// <summary>
/// this method gives the Filename from the long Path
/// </summary>
/// <param name="strString">path of file</param>
/// <returns>return string value</returns>
private string FileName(string strString)
{
return strString.Substring(strString.LastIndexOf("\"));
}
/// <summary>
/// This method is used to get size
/// </summary>
/// <param name="strFileZ">array of files</param>
/// <returns>return long type value</returns>
private long GetSizes(string[] strFileZ)
{
long intSizeToReturn = 0;
foreach (string a in strFileZ)
{
FileStream tmpFS = new FileStream(a, FileMode.Open);
intSizeToReturn += tmpFS.Length;
tmpFS.Close();
}
return intSizeToReturn;
}
}
回答by HasanG
回答by Nimrod
I'm gonna roll the dice that you will eventually respond...
我要掷骰子,你最终会回应......
Assuming that you can handle the file upload just fine, you can use ffmpegto convert the file to FLV format and grab a thumbnail. As Hasan mentioned, ffmpeg works great, plus it has been around a while with lots of support. It's a command line program that operates on parameters, which means you can use it from C#.
假设您可以很好地处理文件上传,您可以使用ffmpeg将文件转换为 FLV 格式并抓取缩略图。正如 Hasan 提到的,ffmpeg 效果很好,而且它已经有一段时间了,得到了很多支持。它是一个对参数进行操作的命令行程序,这意味着您可以在 C# 中使用它。
You will need to download ffmpeg (exe, no install needed). You can use System.Diagnostics
to execute ffmpeg and pass it parameters.
您将需要下载 ffmpeg(exe,无需安装)。您可以使用System.Diagnostics
来执行 ffmpeg 并为其传递参数。
Convert video file to FLV
将视频文件转换为 FLV
System.Diagnostics.Process.Start("ffmpeg.exe",
"-i SourceVideoFile.avi ConvertedVideoFile.flv");
Capture thumbnail
捕获缩略图
System.Diagnostics.Process.Start("ffmpeg.exe",
"-i SourceVideoFile.avi -f image2 -s 320x240 thumbnail.png");
You can also use System.Diagnostics.ProcessStartInfo
if you need more control, need to capture output, etc.
System.Diagnostics.ProcessStartInfo
如果您需要更多控制,需要捕获输出等,您也可以使用。
Once you have the new video file, you should be able to figure out how to play it in a browser :-) If not, take a look at VideoJSor Flowplayer.
一旦你有了新的视频文件,你应该能够弄清楚如何在浏览器中播放它 :-) 如果没有,看看VideoJS或Flowplayer。