Skip to content

Commit

Permalink
HLS support
Browse files Browse the repository at this point in the history
This change adds the (tiny) changes required to the HLS demuxer for it
to support jsfetch as a backend, and thus to support HLS on platforms
that provide W3C fetch.
  • Loading branch information
Yahweasel committed Nov 6, 2023
1 parent 058d926 commit 7d359f6
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 13 deletions.
2 changes: 2 additions & 0 deletions configs/all/ffmpeg-config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@
--enable-decoder=qtrle
--enable-encoder=qtrle
--enable-protocol=jsfetch
--enable-demuxer=hls
--enable-muxer=hls
--enable-libopenh264
--enable-decoder=libopenh264
--enable-encoder=libopenh264
1 change: 1 addition & 0 deletions configs/mkconfigs.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const configs = [
["prores", ["format-mp4", "format-webm", "swscale", "codec-prores"]],
["qtrle", ["format-mov", "swscale", "codec-qtrle"]],
["jsfetch", ["protocol-jsfetch"]],
["hls", ["format-hls"]],

// Patent and/or license encumbered encoders
["mediarecorder-openh264", ["format-ogg", "format-webm", "codec-libopus", "format-mp4", "codec-aac", "format-flac", "codec-flac", "swscale", "libvpx", "codec-libvpx_vp8", "decoder-h264", "codec-libopenh264"]],
Expand Down
4 changes: 2 additions & 2 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ Initializes a muxer all at once, opening the file and initializing the format
context. You can provide the format as a libav numerical code (`oformat`) or as
a name (`format_name`), the filename to write to (which can of course be a
device) (`filename`), and/or create it as a writer device automatically
(`device`). You have the option not to open the file (`open=false`), in which
case you will need to provide your own `pb`.
(`device`). You have the option not to open the file (`open=false`, the
default), in which case you will need to provide your own `pb`.

For the streams to mux, each stream is in the form `[number, number, number]`,
consisting of the codec context, `time_base_num`, and `time_base_den`,
Expand Down
3 changes: 2 additions & 1 deletion docs/IO.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ JavaScript's `fetch` function to stream data over HTTP or HTTPS. This is not
currently enabled by default in any build (other than "all"), but using an
experimental build with `jsfetch` enabled, simply use, e.g., the URL
`jsfetch:https://example.com/video.mkv` to use fetch. `jsfetch` does not
currently support seeking or writing, only reading in a stream.
currently support seeking or writing, only reading in a stream. If you enable
the HLS demuxer, `jsfetch` supports reading from HLS streams as well.


## Reading
Expand Down
5 changes: 3 additions & 2 deletions mk/ffmpeg.mk
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,9 @@ build/ffmpeg-$(FFMPEG_VERSION)/PATCHED: build/ffmpeg-$(FFMPEG_VERSION)/configure
cd build/ffmpeg-$(FFMPEG_VERSION) ; ( test -e PATCHED || patch -p1 -i ../../patches/ffmpeg.diff )
touch $@

build/ffmpeg-$(FFMPEG_VERSION)/libavformat/jsfetch.c: build/ffmpeg-$(FFMPEG_VERSION)/configure
cp patches/jsfetch.c $@
build/ffmpeg-$(FFMPEG_VERSION)/libavformat/jsfetch.c: patches/jsfetch.c \
build/ffmpeg-$(FFMPEG_VERSION)/configure
cp $< $@
touch $@

build/ffmpeg-$(FFMPEG_VERSION)/configure: build/ffmpeg-$(FFMPEG_VERSION).tar.xz
Expand Down
5 changes: 3 additions & 2 deletions mk/ffmpeg.mk.m4
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ build/ffmpeg-$(FFMPEG_VERSION)/PATCHED: build/ffmpeg-$(FFMPEG_VERSION)/configure
cd build/ffmpeg-$(FFMPEG_VERSION) ; ( test -e PATCHED || patch -p1 -i ../../patches/ffmpeg.diff )
touch $@

build/ffmpeg-$(FFMPEG_VERSION)/libavformat/jsfetch.c: build/ffmpeg-$(FFMPEG_VERSION)/configure
cp patches/jsfetch.c $@
build/ffmpeg-$(FFMPEG_VERSION)/libavformat/jsfetch.c: patches/jsfetch.c \
build/ffmpeg-$(FFMPEG_VERSION)/configure
cp $< $@
touch $@

build/ffmpeg-$(FFMPEG_VERSION)/configure: build/ffmpeg-$(FFMPEG_VERSION).tar.xz
Expand Down
13 changes: 13 additions & 0 deletions patches/ffmpeg.diff
Original file line number Diff line number Diff line change
Expand Up @@ -11962,6 +11962,19 @@ index cbdf48d..aeb3767 100644
if (ret == 0 && c->follow)
return AVERROR(EAGAIN);
if (ret == 0)
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 8a96a37..ede65d6 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -673,6 +673,8 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url,
is_http = 1;
} else if (av_strstart(proto_name, "data", NULL)) {
;
+ } else if (av_strstart(proto_name, "jsfetch", NULL)) {
+ ;
} else
return AVERROR_INVALIDDATA;

diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index 3b19e0b..474d82d 100644
--- a/libavformat/oggdec.c
Expand Down
13 changes: 7 additions & 6 deletions patches/jsfetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ static int jsfetch_open(URLContext *h, const char *url, int flags, AVDictionary
* Read from a fetch connection (JavaScript side).
*/
EM_JS(int, jsfetch_read_js, (int idx, unsigned char *toBuf, int size), {
var jsfo = Module.libavjsJSFetch.fetches[idx];
return Asyncify.handleAsync(function() { return Promise.all([]).then(function() {
var jsfo = Module.libavjsJSFetch.fetches[idx];
if (jsfo.buf || jsfo.rej) {
// Already have data
var fromBuf = jsfo.buf;
Expand All @@ -109,7 +109,7 @@ EM_JS(int, jsfetch_read_js, (int idx, unsigned char *toBuf, int size), {
if (fromBuf) {
if (fromBuf.done) {
// EOF
return 0;
return -0x20464f45 /* AVERROR_EOF */;
}
if (fromBuf.value.length > size) {
// Return some of the buffer
Expand Down Expand Up @@ -138,9 +138,10 @@ EM_JS(int, jsfetch_read_js, (int idx, unsigned char *toBuf, int size), {
}

// The next data isn't available yet. Force them to wait.
return new Promise(function(res) {
setTimeout(function() { res(-6 /* EAGAIN */); }, 100);
});
return Promise.race([
jsfo.next,
new Promise(function(res) { setTimeout(res, 100); })
]).then(function() { return -6 /* EAGAIN */; });
}); });
});

Expand Down Expand Up @@ -182,6 +183,6 @@ const URLProtocol ff_jsfetch_protocol = {
.priv_data_size = sizeof(JSFetchContext),
.priv_data_class = &jsfetch_context_class,
.flags = URL_PROTOCOL_FLAG_NETWORK,
.default_whitelist = "http,https"
.default_whitelist = "jsfetch,http,https"
};
#endif

0 comments on commit 7d359f6

Please sign in to comment.