Unable to play video streamed using piping server on safari.
kkanhiya opened this issue ยท 27 comments
[INFO] Waiting for 1 receiver(s)...
[INFO] A receiver was connected.
[INFO] Start sending to 1 receiver(s)!
[INFO] All receiver(s) was/were closed halfway.
@kkanhiya
Thank you for reporting. Could you give me more detail? Could you give me your command and video if possible?
I tried to stream a video in Safari, but I could not. However, in Chrome I could in the following commands.
# Twice
$ cat ray.mp4 | pv | curl -T - -H 'Content-Type: video/mp4' https://piping.ml/myvideo
# Open https://piping.ml/myvideo in the browser
# Cancel the command above by the browser
$ cat ray.mp4 | pv | curl -T - -H 'Content-Type: video/mp4' https://piping.ml/myvideo
The first command will be canceled by a browser. Then, you can type the same command again.
Note that the video should be progressive download format (ffmpeg -i input.mp4 -codec copy -movflags faststart output.mp4
).
Actual demo video in Chrome, not Safari
@kkanhiya I found the reason why Safari doesn't play a video. That's because Safari needs HTTP Range Request. As you know, Piping Server streams data, so it can not support HTTP Range.
I found a Japanese reference, I'm looking for an English one (found it!).
References
@nwtgck looks like this is a range problem from safari end but I am still confused why server stops sending video??
Is there any solution to the safari range request problem??
I found some link which can be useful to you. @nwtgck
https://philna.sh/blog/2018/10/23/service-workers-beware-safaris-range-request/
I am still confused why server stops sending video??
I think the Safari disconnects the connection and Piping Server stops sending video. In my comprehension, If a server supports HTTP Range correctly, the server should return 206 Partial Content
status, but Piping Server doesn't and returns 200
. So Safari rejects the connection and disconnects.
Unfortunately, streaming in Piping Server, and HTTP-Range-support is conflicted. In the policy of Piping Server, it never stores user data. I think HTTP-Range-support needs data storing to get arbitrary range.
@nwtgck Today I was trying more things and found that sever stops two times then safari starts to play video as it does in chrome. Kind of strange??
@kkanhiya Do you mean that you should type the send-command twice in Chrome like the following?
# twice
cat ray.mp4 | pv | curl -T - -H 'Content-Type: video/mp4' https://piping.ml/myvideo
cat ray.mp4 | pv | curl -T - -H 'Content-Type: video/mp4' https://piping.ml/myvideo
@kkanhiya
In my own experiment, that's a Chrome specification. It seems to require Content-Type
. So, the following commands work too in Chrome.
# <Open https://piping.ml/myvideo in Chrome>
# Just send Content-Type
curl -X POST -H 'Content-Type: video/mp4' https://piping.ml/myvideo
# Streaing video
cat ray.mp4 | curl -T - https://piping.ml/myvideo
When I misunderstand your question, tell me.
Rajats-MBP:Downloads kibbcom$ cat tester.mp4 | curl -T - -H 'Range:200-2000' https://piping.ml/myvideolive
[INFO] Waiting for 1 receiver(s)...
[INFO] 1 receiver(s) has/have been connected.
[INFO] Start sending to 1 receiver(s)!
[INFO] All receiver(s) was/were closed halfway.
Rajats-MBP:Downloads kibbcom$ cat tester.mp4 | curl -T - -H 'Range:200-2000' https://piping.ml/myvideolive
[INFO] Waiting for 1 receiver(s)...
[INFO] 1 receiver(s) has/have been connected.
[INFO] Start sending to 1 receiver(s)!
[INFO] All receiver(s) was/were closed halfway.
Rajats-MBP:Downloads kibbcom$ cat tester.mp4 | curl -T - -H 'Range:200-2000' https://piping.ml/myvideolive
[INFO] Waiting for 1 receiver(s)...
[INFO] 1 receiver(s) has/have been connected.
[INFO] Start sending to 1 receiver(s)!
[INFO] Sent successfully!
Then video gets played in safari.
@kkanhiya Now, I understand what you did, but I have no idea why it worked and I was surprised.
I tried your commands several times, but I could not play it on Safari on my Mac.
In the implementation of current Piping Server, sender's header of Range: ooo
is not passed to a receiver. (in this case, the sender is your curl
. The receiver is your Safari.) So, technically, I think the curl commands are the same as cat tester.mp4 | curl -T - https://piping.ml/myvideolive
.
Could you tell me how big your test.mp4
is? Maybe, it depends on the size, but I'm not sure.
@kkanhiya Thank you so much for recording and submitting your demo video! I'm very surprised. I think this is a great finding. I'd like to know the details.
You seem to play video on HTML. Could you give me your HTML? Because I play a video directly in Safari, opening https://piping.ml/myvideolive directly in the URL box.
@kkanhiya Finally, I could play on Safari! I can play without HTML. But I have no idea how Safari works.
But I think the following Safari's requests can be helpful to understand Safari in Network tab. I'll look into it.
@kkanhiya This may be a unique phenomenon in piping.ml
. I have another Piping Server ppng.ml
, and I did the same thing, but I could not play it on Safari. Both piping.ml
and 'ppng.ml' uses different reverse-proxy software. That may affect this phenomenon.
Which reverse-proxy software is being used?? More information can be useful in solving this bug.
piping.ml
uses https://github.com/http-party/node-http-proxyppng.ml
uses https://caddyserver.com/ and https://github.com/http-party/node-http-proxy- client <=> Caddy <=> node-http-proxy <=> Piping Server
on uncaughtException TypeError: Cannot read property 'writev' of undefined
at ServerHttp2Stream._writev (internal/http2/core.js:1356:24)
at doWrite (_stream_writable.js:395:12)
at clearBuffer (_stream_writable.js:501:5)
at onwrite (_stream_writable.js:449:7)
at WriteWrap.afterDoStreamWrite [as oncomplete] (internal/http2/core.js:1133:9)
at ServerHttp2Stream.finishStreamDestroy (internal/http2/core.js:1496:12)
at runCallback (timers.js:794:20)
at tryOnImmediate (timers.js:752:5)
at processImmediate [as _immediateCallback] (timers.js:729:5)
Exception on the server logs. Whenever safari disconnects.
@kkanhiya I did a quick search and found nodejs/node#16797. The error message looks similar.
@nwtgck true looks like a node error. I am using node v10.8.0, seems there is no fix to this error
@kkanhiya Do you mean that this Safari issue is caused by another problem, not #171 (comment)?
@nwtgck Either node has not fixed safari problem in v10.8 or there is some either problem.
@nwtgck
There is no error in the new version of the node but still, the issue is not resolved as we need to fire command 3 times to play on safari.
@kkanhiya Thank you very much for your trying.
I think the issue is under desktop Safari, not Piping Server. As I mentioned, real-time streaming and HTTP Range is a conflicted idea. iOS Safari requires HTTP Range. So, I'd like to close this issue.
iOS Safari requires HTTP Range : https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/CreatingVideoforSafarioniPhone/CreatingVideoforSafarioniPhone.html#//apple_ref/doc/uid/TP40006514-SW6.