Asp.net mvc 使用MVC FileStream播放视频文件时出现问题

Asp.net mvc 使用MVC FileStream播放视频文件时出现问题,asp.net-mvc,video-streaming,html5-video,mediaelement.js,Asp.net Mvc,Video Streaming,Html5 Video,Mediaelement.js,我正在尝试使用以下代码检索视频文件以向用户播放: public class VideoController : Controller { public VideoResult GetMP4Video(string videoID) { if (User.Identity.IsAuthenticated) { string clipLocation = string.Format("{0}\\Completed\\{1}.mp

我正在尝试使用以下代码检索视频文件以向用户播放:

public class VideoController : Controller
{
    public VideoResult GetMP4Video(string videoID)
    {
        if (User.Identity.IsAuthenticated)
        {
            string clipLocation = string.Format("{0}\\Completed\\{1}.mp4", ConfigurationManager.AppSettings["VideoLocation"].ToString(), videoID);

            using (FileStream stream = new FileStream(clipLocation, FileMode.Open))
            {
                FileStreamResult fsResult = new FileStreamResult(stream, "video/mp4");
                VideoResult result = new VideoResult(ReadFully(fsResult.FileStream), "video/mp4");

                return result;
            }
        }
        else
        {
            return null;
        }
    }

    private static byte[] ReadFully(Stream input)
    {
        byte[] buffer = new byte[32 * 1024];
        using (MemoryStream ms = new MemoryStream())
        {
            int read;
            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
            return ms.ToArray();
        }
    }
}
用于向客户端显示我正在使用的媒体元素:

<!-- Video Player Here -->
<video width="640" height="360" poster="@Url.Content(string.Format("~/Videos/{0}_2.jpg", Model.VideoID))" controls="controls" preload="none">
<!-- MP4 for Safari, IE9, iPhone, iPad, Android, and Windows Phone 7 -->
<source type="video/mp4" src="@Url.Action("GetMP4Video", "Video", new { videoID = Model.VideoID })" />
<!-- Flash fallback for non-HTML5 browsers without JavaScript -->
    <object width="320" height="240" type="application/x-shockwave-flash" data="@Url.Content("~/Scripts/ME/flashmediaelement.swf")">
        <param name="movie" value="@Url.Content("~/Scripts/ME/flashmediaelement.swf")" />
        <param name="flashvars" value="controls=true&file=@Url.Action("GetMP4Video", "Video", new { videoID = Model.VideoID })" />
        <!-- Image as a last resort -->
        <img src="myvideo.jpg" width="320" height="240" title="No video playback capabilities" />
    </object>
</video>


但问题是,文件似乎没有播放,或者至少不一致。此外,视频中的搜索似乎也无法正常工作。我想我的问题是,这是一种可以接受的向用户提供视频的方式吗?如果是这样,我错在哪里了?我认为重要的是,我对视频非常陌生,而且我在学习的过程中也学到了很多东西。任何帮助都将不胜感激。

是的,您试图将Web服务器提供的mp4文件放入嵌入HTML文件的播放机中,但无法正常播放(除非该文件相对来说非常小,或者您的internet连接速度非常快,因此文件可以快速下载到浏览器的临时文件夹中)

要正确传输视频文件,请执行以下任何步骤

  • 使用Windows media Server/Flash media Server。通过Windows Media Encoder或flash Media Encoder将网络摄像头推送到服务器,并使用服务器实时链接通过任何合适的播放器(如jwplayer)链接到您的网站

  • 使用Windows Media Encoder将您的网络摄像头传输给任何没有服务器参与的人。当编码器启动时,您将获得一个URL来查看您的流,您可以使用它在站点中发布

  • 使用第三方流媒体服务,他们为您提供一个发布点来发布您的网络摄像头流,并使用他们提供的链接将其显示在您的网站上。(通过LiveStream向brighcove或Mogulus查询


  • 希望这能有所帮助。

    这对我很有用。改编自:


    啊,多好的问题啊!我正在为我自己的一个项目做同样的事情..我们不能指定直接文件,所以我们如何才能为mp4流提供服务器?
     internal static void StreamVideo(string fullpath, HttpContextBase context)
        {
            long size, start, end, length, fp = 0;
            using (StreamReader reader = new StreamReader(fullpath))
            {
    
                size = reader.BaseStream.Length;
                start = 0;
                end = size - 1;
                length = size;
                // Now that we've gotten so far without errors we send the accept range header
                /* At the moment we only support single ranges.
                 * Multiple ranges requires some more work to ensure it works correctly
                 * and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
                 *
                 * Multirange support annouces itself with:
                 * header('Accept-Ranges: bytes');
                 *
                 * Multirange content must be sent with multipart/byteranges mediatype,
                 * (mediatype = mimetype)
                 * as well as a boundry header to indicate the various chunks of data.
                 */
                context.Response.AddHeader("Accept-Ranges", "0-" + size);
                // header('Accept-Ranges: bytes');
                // multipart/byteranges
                // http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
    
                if (!String.IsNullOrEmpty(context.Request.ServerVariables["HTTP_RANGE"]))
                {
                    long anotherStart = start;
                    long anotherEnd = end;
                    string[] arr_split = context.Request.ServerVariables["HTTP_RANGE"].Split(new char[] { Convert.ToChar("=") });
                    string range = arr_split[1];
    
                    // Make sure the client hasn't sent us a multibyte range
                    if (range.IndexOf(",") > -1)
                    {
                        // (?) Shoud this be issued here, or should the first
                        // range be used? Or should the header be ignored and
                        // we output the whole content?
                        context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
                        throw new HttpException(416, "Requested Range Not Satisfiable");
    
                    }
    
                    // If the range starts with an '-' we start from the beginning
                    // If not, we forward the file pointer
                    // And make sure to get the end byte if spesified
                    if (range.StartsWith("-"))
                    {
                        // The n-number of the last bytes is requested
                        anotherStart = size - Convert.ToInt64(range.Substring(1));
                    }
                    else
                    {
                        arr_split = range.Split(new char[] { Convert.ToChar("-") });
                        anotherStart = Convert.ToInt64(arr_split[0]);
                        long temp = 0;
                        anotherEnd = (arr_split.Length > 1 && Int64.TryParse(arr_split[1].ToString(), out temp)) ? Convert.ToInt64(arr_split[1]) : size;
                    }
                    /* Check the range and make sure it's treated according to the specs.
                     * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
                     */
                    // End bytes can not be larger than $end.
                    anotherEnd = (anotherEnd > end) ? end : anotherEnd;
                    // Validate the requested range and return an error if it's not correct.
                    if (anotherStart > anotherEnd || anotherStart > size - 1 || anotherEnd >= size)
                    {
                        context.Response.ContentType = MimeMapping.GetMimeMapping(fullpath);
                        context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
                        throw new HttpException(416, "Requested Range Not Satisfiable");
                    }
                    start = anotherStart;
                    end = anotherEnd;
    
                    length = end - start + 1; // Calculate new content length
                    fp = reader.BaseStream.Seek(start, SeekOrigin.Begin);
                    context.Response.StatusCode = 206;
                }
            }
            // Notify the client the byte range we'll be outputting
            context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
            context.Response.AddHeader("Content-Length", length.ToString());
            // Start buffered download
            context.Response.WriteFile(fullpath, fp, length);
            context.Response.End();
    
        }