Stream MP4 Video From Seek Position in ASP.NET

北城余情 提交于 2019-12-06 13:16:50

问题


I am facing problem while streaming mp4 video from seek position. Its streaming properly from start.

First problem is while mp4 video is streaming via jw player flash player. When user click on time bar to start streaming mp4 video from any other part of video, jw player will send start param along with time information e.g

http://[url]/stream/mp4.ashx?file=Madagascar3-trailer-48861c.mp4&start=53.71

So jwplayer send time interval to seek mp4 streaming from.

I am using the following code to convert approx time interval to bytes as seek will start via bytes.

 double total_duration = Convert.ToDouble(context.Request.Params["d"]);
 double startduration = Convert.ToDouble(context.Request.Params["start"]);
 double length_sec = (double)size / total_duration; // total length per second
 start = (long)(length_sec * startduration);

Here is complete sample code i am using to start streaming from seek position e.g 53.71

private void ChunkDownload(string fullpath, HttpContext 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;

        double total_duration = Convert.ToDouble(context.Request.Params["d"]);
        double startduration = Convert.ToDouble(context.Request.Params["start"]);
        double length_sec = (double)size / total_duration; // total length per second
        start = (long)(length_sec * startduration);

        context.Response.AddHeader("Accept-Ranges", "0-" + size);
        long anotherStart = start;
        long anotherEnd = end;

        // 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.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());

    context.Response.WriteFile(fullpath, fp, length);
    context.Response.End();

}

But it failed to recognize as valid mp4 stream either by player or checking stream url directly.

Can anyone help me to fix this issue.


回答1:


After googled, there are no related APIs found.

You might check the workaround if the problem can't be fixed.

If possible, please provide more information for further study.




回答2:


Agreed, you cannot just seek an mp4/m3u8 file like that.

But I think you cannot find the solution or workaround for this, we have senior iPhone developers and external consultant in my iPhone development team for trial and error, we spend so many resources but the problem still cannot fix.




回答3:


There is no valid content type definition. Try by setting ContentType as video/mp4.

UPDATE

While content type is defined and according to your code the http status code is 206, I suggest you to check this page: 206 Partial Content




回答4:


Muhammad,

I notice you are doing a lot of calculating and manipulation of the content headers. Perhaps when you do all the math on those it is resulting in a header that is not valid because of extra decimal places (making it invalid) or some other issue with those settings.

Meaning, I suggest you do the following:

  1. Run a sample video with streaming from a site using the same player, etc. then use a tool to view the headers while it's working successfully. Just to have a baseline set of headers and valid value formats to compare against.

  2. Run your application and track the headers after you've set them, perhaps like so: how to dump response headers in ASP.Net Even better, install 'Live HTTP Headers' FireFox plug-in or something along those lines.

Compare the working set of headers to yours. Do you see something odd in the values you are setting? Is it possible the content range/length/etc. is somehow offset or invalid? Just look for consistency, a small mistake could easily break the entire request.

Maybe I'm missing something here, but I hope that sparks some ideas.




回答5:


I don't think you can just seek an mp4 file like that. Even if you have the headers you'll need to seek to an I-frame for the video to be playable. You're very likely using the wrong APIs for this.




回答6:


I won't comment on the response-stuff in this post but one issue you definitely have is the MP4 parsing. Unlike MP3 you cannot easily convert a time offset into a byte range like this. You'll need to parse the mp4 moov element and lookup the right chunk in the relevant tracks based on the time offset you're interested in. It goes like this: moov->trak->mdia->minf->stbl->stts The stts box will give you the sample to time mapping you need.



来源:https://stackoverflow.com/questions/9843166/stream-mp4-video-from-seek-position-in-asp-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!