通过.NET HTML5的流媒体的MP4视频 [英] Streaming MP4 video through .NET HTML5

查看:245
本文介绍了通过.NET HTML5的流媒体的MP4视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个测试网页,其中将包含HTML5视频标签,这将使转换的视频进行播放。我能够成功转换的视频,并在服务器上本地存储这些,但我希望能够通过另一个.aspx页流的所有视频。

I am trying to create a test page which will contain a HTML5 VIDEO tag which will allow converted videos to be played. I am successfully able to convert the videos and store these locally on the server but I'd like to be able to stream all videos through another .aspx page.

假设我有一个player.aspx网页,其中将包含HTML code和getvideo.aspx页面,该页面会做什么,除了提供视频二进制,我认为以下code会很好地工作在我的球员.aspx页面中:

Assuming I have a player.aspx page which will contain the HTML code and getvideo.aspx page which will do nothing except provide the video binary, I thought that the following code would work fine in my player.aspx page:

<div style="text-align:center">   
<video controls autoplay id="video1" width="920">  
    <source src=""http://www.mywebsite.com/getvideo.aspx?getvideo=1"" type=""video/mp4">  
    Your browser does not support HTML5 video.  
</video>  

该getvideo.aspx页面包含以下vb.net code:

The getvideo.aspx page contains the following vb.net code:

Response.clearheaders
Response.AddHeader("Content-Type", "video/mp4")
Response.AddHeader("Content-Disposition", "inline;filename=""newvideo.mp4""")

dim Err as string = ""
Dim iStream As System.IO.Stream

' Buffer to read 10K bytes in chunk:
Dim buffer(buffersize) As Byte
' Length of the file:
Dim length As Integer

' Total bytes to read:
Dim dataToRead As Long

' Identify the file to download including its path.
Dim filepath As String = "./outout/videos/newvideo.mp4"

' Identify the file name.
Dim filename As String = System.IO.Path.GetFileName(filepath)

' Open the file.
try
    iStream = New System.IO.FileStream(filepath, System.IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
catch ex as exception
    throw new exception("Could not create FileStream for [" & filepath & "], error follows." & vbcrlf & ex.toString)
end try

Try
    ' Total bytes to read:
    dataToRead = iStream.Length

    ' Read the bytes.
    While dataToRead > 0
        ' Verify that the client is connected.
        If system.web.httpcontext.current.Response.IsClientConnected Then
            ' Read the data in buffer
            length = iStream.Read(buffer, 0, buffersize)
            ' Write the data to the current output stream.
            system.web.httpcontext.current.Response.OutputStream.Write(buffer, 0, length)
           ' Flush the data to the HTML output.
           system.web.httpcontext.current.Response.Flush()

           ReDim buffer(buffersize) ' Clear the buffer
           dataToRead = dataToRead - length
       Else
           'prevent infinite loop if user disconnects
           dataToRead = -1
       End If
    End While

Catch ex As Exception
    ' Trap the error, if any.
    err =  "Error accessing " & filepath & " : " & ex.tostring
Finally
    If IsNothing(iStream) = False Then
        ' Close the file.
        iStream.Close()
    End If
End Try

if err<>"" then throw new exception( err )

我得到我的页面输出为HTML视频播放器(Chrome浏览器的基本播放器),这似乎超时,播放按钮变为灰色。在Chrome开发人员工具的网络工具显示它的下载45MB,并得到一个200响应code。这表明,我认为这是工作的罚款。虽然我得到了取消状态的第二个GET请求?

All I get on my page output is a HTML video player (chrome's basic player) which seems to time out and the PLAY button goes grey. The Network tool in the Chrome Developer tools shows that it's downloading 45mb and gets a 200 response code. This suggests to me that it is working fine. Although I get a second GET request with the status of "Cancelled"?

如果我访问www.mywebsite.com/output/videos/myvideo.mp4那么这​​起在浏览器精细,所以我知道IIS被配置为正确的视频流。

If I visit www.mywebsite.com/output/videos/myvideo.mp4 then this plays in the browser fine so I know IIS is configured to correctly stream video.

另外,如果我改变响应内容部署到附件,然后在浏览器中正确打算什么时候我的ASPX页面,但是这也没有正确的HTML播放机上播放强制下载的视频。是不是有什么'聪明'的HTML5视频标签,它是由通过.NET提供了视频停止.aspx文件怎么回事?还是我缺少一个响应头?

Also if I change the response content disposition to "attachment" then the browser correctly forces a download of the video when going to my ASPX page, but this also doesn't correctly play on the HTML player. Is there something 'clever' going on with the HTML5 VIDEO tag which is stopping a .aspx file from serving up video via .net? Or am I missing a response header?

谢谢!

推荐答案

修复!

这里的问题是presumably是与HTML5视频实现窄幅请求。如果没有配套的范围,要求在网页中被用来服务于视频,他们只是将无法正常工作。

The problem here is presumably something to do with the HTML5 video implementation of range-requests. Without supporting range-requests in the page being used to SERVE the video, they just won't work.

这是由斯科特·米切尔它把我的情况下,这非常有帮助的帖子: 的http://dotnetslackers.com/articles/aspnet/Range-Specific-Requests-in-ASP-NET.aspx

It was this very helpful post from Scott Mitchell which set me on the case: http://dotnetslackers.com/articles/aspnet/Range-Specific-Requests-in-ASP-NET.aspx

和克里斯·库尔森另一个有用的帖子里面提供的实现在C#中的解决方案! 的http://dotnetslackers.com/articles/aspnet/Range-Specific-Requests-in-ASP-NET.aspx

And another helpful post from Chris Coulson which provided the implementation in C# for the solution! http://dotnetslackers.com/articles/aspnet/Range-Specific-Requests-in-ASP-NET.aspx

我的vb.netÇ克里斯$ C $的端口发现是下面,实现它只是把这个在你的页面:

My vb.net port of the code Chris found is below, to implement it simply put this in your page:

system.web.httpcontext.current.Response.ContentType = "video/" & convertFormat.toString
RangeDownload(convertedVideo, system.web.httpcontext.current)

VB.NET code:

VB.NET CODE:

private sub RangeDownload( fullpath as string, context as HttpContext)

    dim size as long
    dim start as long
    dim theend as long
    dim length as long
    dim fp as long =0
    using reader as new StreamReader(fullpath)
        size = reader.BaseStream.Length
        start = 0
        theend = 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 (not String.IsNullOrEmpty(context.Request.ServerVariables("HTTP_RANGE"))) then
            dim anotherStart as long = start
            dim anotherEnd as long = theend
            dim arr_split as string() = context.Request.ServerVariables("HTTP_RANGE").Split("=") 'new char[] { Convert.ToChar("=") })
            dim range as string = arr_split(1)

            '// Make sure the client hasn't sent us a multibyte range
            if (range.IndexOf(",") > -1) then
                '// (?) 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 & "-" & theend & "/" & size)
                throw new HttpException(416, "Requested Range Not Satisfiable")
            end if

            '// 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("-")) then
                '// The n-number of the last bytes is requested
                anotherStart = size - Convert.ToInt64(range.Substring(1))
            else
                arr_split = range.Split("-")
                anotherStart = Convert.ToInt64(arr_split(0))
                dim temp as long = 0
                if (arr_split.Length > 1 andalso Int64.TryParse(arr_split(1).ToString(), temp)) then
                    anotherEnd =  Convert.ToInt64(arr_split(1))
                else
                    anotherEnd = size
                end if
            end if
            '/* 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.
            if (anotherEnd > theend) then
                anotherEnd = theend
            else
                anotherEnd = anotherEnd
            end if
            '// Validate the requested range and return an error if it's not correct.
            if (anotherStart > anotherEnd or anotherStart > size - 1 or anotherEnd >= size) then
                context.Response.AddHeader("Content-Range", "bytes " + start + "-" + theend + "/" + size)
                throw new HttpException(416, "Requested Range Not Satisfiable")
            end if

            start = anotherStart
            theend = anotherEnd

            length = theend - start + 1 '// Calculate new content length
            fp = reader.BaseStream.Seek(start, SeekOrigin.Begin)
            context.Response.StatusCode = 206
        end if
    end using

    '// Notify the client the byte range we'll be outputting
    context.Response.AddHeader("Content-Range", "bytes " & start & "-" & theend & "/" & size)
    context.Response.AddHeader("Content-Length", length.ToString())
    '// Start buffered download
    context.Response.WriteFile(fullpath, fp, length)
    context.Response.End()
end sub

这篇关于通过.NET HTML5的流媒体的MP4视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆