fHDHR / fHDHR_plugin_origin_ceton

Do What The F*ck You Want To Public License
1 stars 4 forks source link

[Solved, then turned into a hangout thread] Tune Failed: Could Not Create Socket #16

Closed arrmo closed 2 years ago

arrmo commented 2 years ago

Hi,

OK, this is so cool - really like how this all works together. Thanks!

Just having a bit of an issue with my Ceton card. I try to have Plex tune to a channel, but seeing this error (and Plex complains about it of course),

[2022-01-21 17:55:40,333] INFO - Client has requested stream for ceton channel 4 KDFW FOX KDFW FOX.
[2022-01-21 17:55:40,333] INFO - Selected Stream Parameters: method=direct duration=0 origin_quality=None transcode_quality=None.
[2022-01-21 17:55:40,334] INFO - Attempting to Select an available tuner for this stream.
[2022-01-21 17:55:40,334] INFO - Tuner #0 Acquired.
[2022-01-21 17:55:40,335] INFO - ceton Tuner #0 to be used for stream.
[2022-01-21 17:55:40,361] INFO - Selected Ceton tuner#: 0
[2022-01-21 17:55:40,362] INFO - Ceton tuner 0 to be started
[2022-01-21 17:55:40,579] INFO - Preparing Ceton tuner 0 on port: 43534
[2022-01-21 17:55:41,586] INFO - Initiate streaming channel 4 from Ceton tuner#: 0 
[2022-01-21 17:55:41,587] INFO - Preparing Stream...
[2022-01-21 17:55:41,587] INFO - Attempting to create socket to listen on.
[2022-01-21 17:55:41,588] INFO - Created TCP socket at 192.168.2.64:57467.
[2022-01-21 17:55:41,588] INFO - Created UDP socket at 192.168.2.64:43412.
[2022-01-21 17:55:41,589] INFO - Closing UDP socket at 192.168.2.64:43412.
[2022-01-21 17:55:41,590] INFO - Closing TCP socket at 192.168.2.64:57467.
[2022-01-21 17:55:41,590] ERROR - TunerError: 806 - Tune Failed: Could Not Create Socket: 'username'
[2022-01-21 17:55:41,591] INFO - Tuner #0 Released.
[2022-01-21 17:55:41,595] INFO - 192.168.2.65 - - [2022-01-21 17:55:41] "GET /api/tuners?method=stream&channel=4&origin=ceton&stream_method=direct&accessed=http%3A//192.168.2.64%3A5006/hdhr/ceton/auto/v4 HTTP/1.1" 503 2424 1.265516
{'channel': '4', 'channel_name': 'KDFW FOX', 'channel_callsign': 'KDFW FOX', 'origin': 'ceton', 'method': 'direct', 'duration': 0, 'origin_quality': None, 'transcode_quality': None, 'accessed': 'http://192.168.2.64:5006/hdhr/ceton/auto/v4', 'base_url': 'http://192.168.2.64:5006', 'client': '192.168.2.65', 'client_id': 'e21ddcb0-eae3-4b25-a6a1-c014b2985fb2', 'stream_info': {'url': 'udp://127.0.0.1:43534', 'headers': None}, 'true_content_type': 'video/mpeg', 'content_type': 'video/mpeg'}

Absolutely could be me. I'm not sure that I need to set / define 'username' ... or do I?

And to clarify, this is for an InfiniTV 4, PCIe.

BTW, a bit of fiddling here, I was able to look at the Ceton web interface, manually get a channel to tune, and then right after that stream from the appropriate device to mplayer. Just to let you know, the card is working 🤣. Oh, and this is from Postman - used that to confirm the "API" is working.

Requests, channel change
import requests

url = "http://192.168.200.1/channel_request.cgi"

payload='instance_id=3&channel=593'
headers = {
  'Content-Type': 'application/x-www-form-urlencoded'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)

Thanks!

DanAustinGH commented 2 years ago

With the changes you already have for reading from the hardware, you might also be able to use direct streaming. worth a try...

arrmo commented 2 years ago

Yep! Plan to give it a roll tonight, will let you know. Just not quite sure which of the changes are meant to be included for this - few updates above, sorry.

DanAustinGH commented 2 years ago

I'd include these-

deathbybandaid commented 2 years ago

I wish we could make the direct_rtp method actually work for this as well someday

DanAustinGH commented 2 years ago

I'll take another look at that soon. I had a very similar implementation last year. It would process a handful of packets and then crash...

deathbybandaid commented 2 years ago

I recently made changes to the tuner buffer to re-attempt a stream 3 times before failing out, all while the buffered chunks still play in a client.

arrmo commented 2 years ago

Hmmm ... OK, I have device detection updated (in a new local testing branch), and streamurl ... but when I try to merge in the latest from upstream/main, it says I'm already up to date (but clearly I'm not, when looking at the code.

Any thoughts?

arrmo commented 2 years ago

Never mind - I see my dumb 🙄. I was in plugins (ceton) ... different upstream. LOL!

arrmo commented 2 years ago

Close! 😄. OK, if I leave stream_method = ffmpeg, it works fine. With stream_method = direct, it's trying, but I get the error,

[2022-01-24 16:28:23,334] INFO - Client has requested stream for ceton channel 505 KXAS NBC HD KXAS NBC HD.
[2022-01-24 16:28:23,335] INFO - Selected Stream Parameters: method=direct duration=0 origin_quality=None transcode_quality=None.
[2022-01-24 16:28:23,335] INFO - Attempting to Select an available tuner for this stream.
[2022-01-24 16:28:23,336] INFO - Tuner #0 Acquired.
[2022-01-24 16:28:23,336] INFO - ceton Tuner #0 to be used for stream.
[2022-01-24 16:28:23,362] INFO - Selected Ceton tuner#: 0
[2022-01-24 16:28:23,363] INFO - Ceton tuner 0 to be started
[2022-01-24 16:28:23,508] INFO - Preparing Ceton tuner 0 on port: 46361
[2022-01-24 16:28:24,526] INFO - Initiate PCIe direct streaming, channel 505 from Ceton tuner#: 0 
[2022-01-24 16:28:24,527] INFO - Preparing Stream...
[2022-01-24 16:28:24,527] INFO - Stream Method Detected as a /dev/ hardware device.
[2022-01-24 16:28:24,528] ERROR - TunerError: 806 - Tune Failed: /dev/ceton/ctn91xx_mpeg0_0 PATH does not seem to exist
[2022-01-24 16:28:24,528] INFO - Tuner #0 Released.

I did check, and yes ... that path is correct, and does exist. Thoughts?

Thanks!

deathbybandaid commented 2 years ago

The new direct for hardware is untested and may need some work, as right now I'm doing a check if the path exists as if it was a file.

deathbybandaid commented 2 years ago

https://github.com/fHDHR/fHDHR/blob/main/fHDHR/device/tuners/stream/direct_hardware_stream.py

DanAustinGH commented 2 years ago

Perhaps try os.path.exists instead of os.path.isfile the former should for for character, block, directory and file, while the second is not documented as working for character or block devices (most common type in /dev)

arrmo commented 2 years ago

Exactly what I did :rofl. Now looking at this,

[2022-01-24 16:37:35,675] INFO - Direct Hardware Stream from device: /dev/ceton/ctn91xx_mpeg0_0
[2022-01-24 16:37:36,414] ERROR - Chunk #1 unable to process: 'utf-8' codec can't decode byte 0xbc in position 5: invalid start byte

Checking it!

deathbybandaid commented 2 years ago

Sounds like progress

arrmo commented 2 years ago

Absolutely! And pulling chunks seems to be OK ... looking now why it seems to think it can't handle them. Thanks!

deathbybandaid commented 2 years ago

@arrmo https://github.com/fHDHR/fHDHR/pull/223

deathbybandaid commented 2 years ago

you might want to remove the try/except for testing and write more explicit Exception handling

arrmo commented 2 years ago

Yep. I made a slight change here,

with open(self.stream_args["stream_info"]["url"], 'rb') as device_stream

=> data is binary, not text (agreed?). I have video in Plex now!

But it's a bit "herky-jerky" ... technical term. LOL! Not quite sure why (yet).

DanAustinGH commented 2 years ago

Maybe try tuning bytes per read in your config.ini, double, cut in half to see if either works better and repeat

arrmo commented 2 years ago

Agreed! Was messing with it here in streaming.json (directly), and it does seem to have an impact. In config.ini ... not sure which section to use?

[streaming]
[direct_stream]

And I guess not in [ceton]?

DanAustinGH commented 2 years ago

The code says it gets that value from [streaming]

DanAustinGH commented 2 years ago

You can also set it in the UI. Not sure if it requires a restart, If not it will make testing go much quicker...

deathbybandaid commented 2 years ago

https://github.com/fHDHR/fHDHR/pull/224

arrmo commented 2 years ago

Could be - testing in pyCharm, I stop and restart each time, to make sure. No biggie. Was thinking it may be pyCharm causing it, so I tried from bash ... the same. Changing up / down does have an impact, but non seem quite happy. Wondering about buffering (and samples lost perhaps?)?

BTW, one pain ... in bash, I can't seem to Ctrl-C to get execution to stop, Seems odd.

DanAustinGH commented 2 years ago

I've noticed the Ctrl-C, but I rarely run it manually. Ctrl-Z; kill %1 works for me

You might try multiples of 188 bytes, assuming we are getting good/correct mpegts packets from the card

arrmo commented 2 years ago

Tried 8k * 188 ... perhaps a bit better, but still some glitches.

Wondering if somehow the input needs to be aligned to packets / frames? Will dig into this some. I'm thinking it may make sense to dump out the outgoing packets (just a couple, to compare), in the ffmpeg vs. direct cases.

DanAustinGH commented 2 years ago

Looking at a few HD programs I have recorded from my Ceton. It looks like 8K TS packets is just over 1 second. Losing a fraction of one should not be noticeable. A much larger read would mean a bigger delay during initial tuning, but would also greatly reduced the error%, assuming that when we open the device the first byte is not the 1st in the packet, we would be losing the 1st and last in the read. Does going up to 16k or 32 make any difference? Or dropping to 4k?

And out of curiosity are the /dev/ceton/ctn* character or block devices (or other)?

DanAustinGH commented 2 years ago

Just curious, but what happens if you replace /dev/ceton/ctn91xxmpeg0%s with /dev/ceton/ctn91xxfilter0%s

I read through the device driver driver code and the 188 bytes per packet is on the filter device and the mpeg device use a 3948 bytes per page/packet (no idea where this comes from)

deathbybandaid commented 2 years ago

Just dropping a couple links for ideas....

https://github.com/fHDHR/fHDHR/blob/9aabbc0641b65c65e63630b81048ff328958b43c/data/internal_config/streaming.json#L10

https://github.com/fHDHR/fHDHR/blob/9aabbc0641b65c65e63630b81048ff328958b43c/fHDHR_web/api/tuners.py#L131

https://github.com/fHDHR/fHDHR_plugin_origin_tvheadend/blob/main/origin/__init__.py#L80-L84

I will probably look at moving some of these universal streaming settings to being origin specific. Keep in mind, some config settings are from before fHDHR supported multiple origins.

HOWEVER, I share these links as there is a method for selecting quality profiles. With that in mind, if there's any way to select quality from the origin by changing the /dev/ path, that would be an extra nice addition.

deathbybandaid commented 2 years ago

I like when people actually collaborate, because then it pushes me to make cool updates to the core code. I've taken most of the streaming settings and made them origin specific (at least from the config file), I need to implement a better way of making some of the extra imposed settings more available from the web interface.

https://github.com/fHDHR/fHDHR/pull/225

arrmo commented 2 years ago

Looking at a few HD programs I have recorded from my Ceton. It looks like 8K TS packets is just over 1 second. Losing a fraction of one should not be noticeable. A much larger read would mean a bigger delay during initial tuning, but would also greatly reduced the error%, assuming that when we open the device the first byte is not the 1st in the packet, we would be losing the 1st and last in the read. Does going up to 16k or 32 make any difference? Or dropping to 4k?

This does help! I checked, and my input is ~ 16 Mbps (video) ... so ~ 2 MB/s. If I shoot for ~ 2 MB packets => 1 per second, don't overload the loop. Wondering also about spawning it to another thread?

And out of curiosity are the /dev/ceton/ctn* character or block devices (or other)?

Not sure, sorry! I tried using https://docs.python.org/3/library/pathlib.html#pathlib.Path.is_block_device (and char_device) ... False to both?!?!

Just curious, but what happens if you replace /dev/ceton/ctn91xxmpeg0%s with /dev/ceton/ctn91xxfilter0%s

No output at all - confirmed with mplayer also.

I read through the device driver driver code and the 188 bytes per packet is on the filter device and the mpeg device use a 3948 bytes per page/packet (no idea where this comes from)

That helps! OK, so I went with a fixed number of (3948 byte) pages / packets, 2021376 bytes. Used this, and also did buffering, to avoid lost bytes while processing them,

with open(self.stream_args["stream_info"]["url"], 'rb', buffering=self.bytes_per_read) as device_stream:

MUCH cleaner - almost perfect (just not 100% sure, that's all). But working, for sure. If I go down 2x ... a bit iffy => too fast for the loop to handle? And 2x larger, it is slower to start, like you say.

FYI, I did a stream to file (cat output), and then opened the file in Wireshark (it recognizes mpeg2ts!) ... packets starting right at the beginning of my file => so thinking it's a block (packet) based device?

Thoughts?

arrmo commented 2 years ago

@deathbybandaid I agree! And we're aligned. Let me pull your code, drop the buffering I added 😆

arrmo commented 2 years ago

FYI, only part way through, but I like this so far https://tsduck.io/download/docs/mpegts-introduction.pdf

arrmo commented 2 years ago

OK, I take it back (a little) about the video - I was getting fooled a bit, as Plex was transcoding. Arrgh. Once I went to Direct Stream from Plex, I could see it few more artifacts.

Odd to me, where / how it's getting dropped. Thinking buffering should help!

deathbybandaid commented 2 years ago

Might need to increase the buffer size,,,

Defaults to 3 chunks

deathbybandaid commented 2 years ago

To clarify, the stream code itself is a giant buffer layer on top of the layer that pulls the chunks of video

https://github.com/fHDHR/fHDHR/blob/main/fHDHR/device/tuners/stream/__init__.py#L123

deathbybandaid commented 2 years ago

And with my new code push, this should work per origin or the universal streaming setting

arrmo commented 2 years ago

Meaning that the buffer (bytes_per_read) can be set for [streaming] or [ceton]? Just to understand.

deathbybandaid commented 2 years ago

Correct

deathbybandaid commented 2 years ago

Because in theory you might run multiple origins with different needs

arrmo commented 2 years ago

Makes complete sense. Still odd to me that something is getting dropped somewhere. Thinking out loud, but for debug ... in addition to sending to Plex, dump the input (from Ceton) and output (to Plex) to a file? Then can try to analyze that?

Thoughts?

deathbybandaid commented 2 years ago

From the fhdhr interface, you can grab m3u to play in vlc and cut plex out of the picture

deathbybandaid commented 2 years ago

Screenshot_20220124-211626_Firefox.jpg

From one f the "play" links

arrmo commented 2 years ago

Perfect! That works ... so I tried it, ffmpeg => no lost (video) frames. But direct - yep. That's good actually, helps to debug, in a non-eyeball way 😜

This means it's on the "input" capture side, right?

Thanks!

deathbybandaid commented 2 years ago

As I have no way to test any of this, and the direct_hardware method is brand new, you might just have to poke at the code to see how to make it work.

On the flipside, a partial stream is progress over no stream at all

arrmo commented 2 years ago

As I have no way to test any of this, and the direct_hardware method is brand new, you might just have to poke at the code to see how to make it work.

Yep, agreed! And that's my plan. Just wanted to make sure I was looking the right place (i.e. input).

On the flipside, a partial stream is progress over no stream at all

Couldn't agree more! Thinking this is great progress - very close.

deathbybandaid commented 2 years ago

The main goal of fHDHR is to be able to pull any video origin, and output however wanted

The hdhr plugin simply does a 302 redirect to the /api/tuners endpoint. It just lets plex believe it's a real HDHR device. You could realistically write any output you wanted, including being available by dlna

arrmo commented 2 years ago

That is so cool! And it really does work very well. This is a minor issue now, great progress IMHO.

Thanks!

arrmo commented 2 years ago

FYI, with both input and output buffers set (to ~ 2 MB, but a fixed number of 3984 packets) ... so far, no dropped video frames (out of 10k). So progress. But odd ... when playing back an m3u, I lose the fHDHR web interface (it becomes non-responsive)? Comes back as soon as I stop the m3u.

I tried playing Plex in parallel (with m3u), but it tried to grab the same tuner => wouldn't let me do it.

Overall, looking quite good, just a few minor things. Thanks!

arrmo commented 2 years ago

Oh, and in the code, I set buffering=0 (file open) ... as you have higher level buffering, correct?