nwtgck/piping-server

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

piping-server-video-streaming mp4 opt

@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??

@kkanhiya

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.

tester.mp4 video is of 2.6mb
videotest

@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.

I made html file as txt. Kindly rename it as .html to make it work.
index.txt

@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.
image

image

image

image

@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.

@kkanhiya

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 Greate report! You might find Node.js bug?

@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.

@kkanhiya I think the latest v10.x is 10.16.0. Are you going to try this version?

image
(from: https://nodejs.org/en/download/releases/)

@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.