gpac / mp4box.js

JavaScript version of GPAC's MP4Box tool
https://gpac.github.io/mp4box.js/
BSD 3-Clause "New" or "Revised" License
1.96k stars 332 forks source link

Seek should bring back range instead of offset #26

Open guypaskar opened 9 years ago

guypaskar commented 9 years ago

It would help a lot if seek would return the range of the segment instead of the ony the starting offset incase I want to download only the needed segment.

What do you think?

cconcolato commented 9 years ago

I saw the discussion about the problem in the demo application that it creates ranges larger than the file size. That's more a problem of the sample downloader than of mp4box.js. I will fix that. For mp4box, what range would you expect to be returned ? range till the end of the file? mp4box.js does not know if the input is a file. Till the last sample? This is assuming that the input is not fragmented otherwise you never know which one is the last sample. What else?

guypaskar commented 9 years ago

I want to be able to download the file by segments. That is, differently from the demo where it download in one size chunks and keep going , I want to download segment segment.

Assuming the input is not fragmented , when the a seek happens , instead of just bringing back the offset which we should start downloading from, to get until what index we should download so we can parse a full segment (which basically is the next segment index -1 so I think it is easy to implement in the seek method)

cconcolato commented 9 years ago

I'm not sure I'm following you. If the input is not fragmented, you don't have fragments and therefore you don't have segments. If the input file is simply fragmented (no sidx), there is no way to tell the size of the fragment before parsing its header, so you cannot know the valid range for the first request, only for the second request per fragment. Then if the input file is segmented, with sidx, using the ondemand DASH file, parsing the sidx box can indeed give you some range info. That's what DASH players do. Not sure why mp4box.js should go in this direction. Am I missing something here?

guypaskar commented 9 years ago

Maybe I'm confused but I'll try to explain again.
The input is not fragmented (regular mp4) and I want to use media source to play that video - very much like in the demo (that is use mp4box to convert it on the fly to be fragmented)

Let's take a look at the function MP4Box.prototype.seek It gets a time and returns a seek info. That seek info has an offset that tells you where we should start downloading more chunks in order to get data that after parsing it will contain the right data and appending it will enable the player to play from the wanted point.

I want to know also the corresponding offset for the next "segment" (and thus the -1 Would give me the end offset of the current segment)

Does that make more sense?

cconcolato commented 9 years ago

I think I understand, maybe I was confused ;) The segment duration (that you can set in the demo app) and the seek are currently not related. You're saying I could relate them to return a range that corresponds to the number of bytes necessary to produce at least one segment (as configured). Interesting. It may not be always possible (e.g. if the input file is fragmented without sidx) but for non-fragmented files this could work. I'll see what I can do.

guypaskar commented 9 years ago

Getting closer.

I'll tell you why I need it. Say I want to fetch 20 seconds in advance from what I have no. I'm making a (fake) seek request to v.currentTime + 20 to get the relevant start offset of where I should download BUT then I want to stop downloading since I have 20 seconds buffer.

Thing is , I want to download Until an end of segment to make sure I have 20 seconds (and not less) and also not download half a segment (that is always make xhrs that are contains multiple complete segments)

Does what I say make sense to you?

It should be only for non-fragment (maybe with some flag for the developer...)

Thanks for trying to solve this.

cconcolato commented 9 years ago

Actually, I thought of the seek method for that too. It's separate from the downloader for that purpose. Why don't you want to use two seek operations: one to get the file offset at v.currentTime+20 and one at v.currentTime+20+segmentDuration ?

Also, be careful when you say "make xhrs that are contains multiple complete segments", this might be misleading. Segments don't exist in the original file (since it's not fragmented), so they won't be in the XHR. In the XHR you will have the samples/frames that will be used to make segments according to the settings you gave to mp4box.js.

guypaskar commented 9 years ago

That would work great, but How do I know what is the the segment duration in time? I'm not sure...

Yes, this might be misleading. When I say "make xhrs that are contains multiple complete segments" I mean xhrs that contain data (frames/samples) that can be parsed for a complete segment and not , for example 1.9 segments and then the user is waiting for the next download although the player already has most of the desired segment.

cconcolato commented 9 years ago

The application sets the segment duration, see the demo app slider called "Segment Duration (number of frames)".

Segments don't exist in the original file. And they are not even needed by MSE, only fragments are. But since I generate (so far) a fragment per frame (!), and since it is too computationally expensive for the browser to process each fragment one by one, I group them in segments. This also allows saving the segments as files. So the segments are only created on the fly for ease of processing on the client side but indeed if the frames to form the whole segments are not there, the segment will not be flushed, so you need to make sure that you fetch all those frames (thus the 2nd call to seek). Is that clearer ?

guypaskar commented 9 years ago

I understand all you said I just don't know how to translate from the Segment Duration (number of frames) to something that is of type time (seconds) to make the second seek.

How do you translate the number of frames to a duration in time?

cconcolato commented 9 years ago

Ah. Indeed. There is no easy way to translate number of frames to a duration in time. I should probably change (or add) the option to segment with a duration and not a number of frames. Would that solve your problem?

guypaskar commented 9 years ago

Yes. I think add would be better. That way one can choose how to define the segment duration.