diff --git a/www/README.md b/www/README.md
index 5c95bf17..fa28938c 100644
--- a/www/README.md
+++ b/www/README.md
@@ -11,6 +11,8 @@
```
+- https://developer.apple.com/documentation/webkit/delivering_video_content_for_safari/
+
**2. [Safari] pc.createOffer**
Don't work in Desktop Safari:
diff --git a/www/index.html b/www/index.html
index 96198f8c..5125c50f 100644
--- a/www/index.html
+++ b/www/index.html
@@ -63,7 +63,7 @@
-
+
diff --git a/www/video-rtc.js b/www/video-rtc.js
index 11ec30be..cac829f8 100644
--- a/www/video-rtc.js
+++ b/www/video-rtc.js
@@ -32,10 +32,10 @@ export class VideoRTC extends HTMLElement {
];
/**
- * [config] Supported modes (webrtc, mse, mp4, mjpeg).
+ * [config] Supported modes (webrtc, mse, hls, mp4, mjpeg).
* @type {string}
*/
- this.mode = "webrtc,mse,mp4,mjpeg";
+ this.mode = "webrtc,mse,hls,mjpeg";
/**
* [config] Run stream when not displayed on the screen. Default `false`.
@@ -324,6 +324,9 @@ export class VideoRTC extends HTMLElement {
if (this.mode.indexOf("mse") >= 0 && "MediaSource" in window) { // iPhone
modes.push("mse");
this.onmse();
+ } else if (this.mode.indexOf("hls") >= 0 && this.video.canPlayType("application/vnd.apple.mpegurl")) {
+ modes.push("hls");
+ this.onhls();
} else if (this.mode.indexOf("mp4") >= 0) {
modes.push("mp4");
this.onmp4();
@@ -554,6 +557,17 @@ export class VideoRTC extends HTMLElement {
this.send({type: "mjpeg"});
}
+ onhls() {
+ this.onmessage["hls"] = msg => {
+ const url = "http" + this.wsURL.substring(2, this.wsURL.indexOf("/ws")) + "/hls/";
+ const playlist = msg.value.replace("hls/", url);
+ this.video.src = "data:application/vnd.apple.mpegurl;base64," + btoa(playlist);
+ this.play();
+ }
+
+ this.send({type: "hls", value: this.codecs("hls")});
+ }
+
onmp4() {
/** @type {HTMLCanvasElement} **/
const canvas = document.createElement("canvas");
diff --git a/www/video-stream.js b/www/video-stream.js
index 22615dc5..9347a6c2 100644
--- a/www/video-stream.js
+++ b/www/video-stream.js
@@ -70,6 +70,7 @@ class VideoStream extends VideoRTC {
this.divError = msg.value;
break;
case "mse":
+ case "hls":
case "mp4":
case "mjpeg":
this.divMode = msg.type.toUpperCase();