Skip to content

Instantly share code, notes, and snippets.

@Juul
Last active May 12, 2023 02:13
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Juul/8adc297cf49675d858976f5d10fffc6e to your computer and use it in GitHub Desktop.
Save Juul/8adc297cf49675d858976f5d10fffc6e to your computer and use it in GitHub Desktop.
How to get a $33 HDMI capture and H264 encoder

This is a guide for how to get a $33 HDMI capture device and H264 encoder that can do 1080p 30 fps or 720p 60 fps. It will only output a H264 encoded stream and is not able to capture the raw HDMI data.

This is just a quick guide based on all the hard work and info from danman's blog post.

Buying

Go to ebay, aliexpress or similar and find a LKV373A sender. It is sold as a device for extending HDMI over ethernet cable. You only need to buy the sender, not the pair of sender and receiver. The sender is actually an HDMI capture and encoder device. It should cost ~$33 shipped. One of the commenters mentioned that you need v3 hardware and that this won't work with v4 hardware so beware!

Updating the firmware

The original firmware is annoying and limited. Upgrading gets you full HD resolution and ability to easily configure IP and which IP to send to (unicast or multicast).

Download the firmware linked from here or here is a direct link, or here it is mirrored on the internet archive. You want to download everything in the directory called IPTV_command_library_and_tool_20160303.

Plug in the HDMI Extender sender to power and to your computer via ethernet.

Set your computer's static IP to e.g. 192.168.1.2 then go to 192.168.1.238 in chromium (firefox seems not to work).

Use the web interface to update the main firmware (not the encoder firmware) with the file IPTV_TX_PKG_v4_0_0_0_20160427.PKG. Wait for it to tell you it's done, then press the reset button on the device once.

It will now have a new IP address. If there is a DHCP server it will get an IP from that, otherwise it will use a 169.254.x.x IP address. You can use wireshark to listen for packets and you will see a bunch from whichever IP it picks. It might always use the same IP, in which case it will be 169.254.151.20. Give yourself a static IP in the same range, e.g. 169.254.151.2. If you have windows you can use the IPTV_Control_Center.exe utility to scan for the encoder device and find it's IP address (it did not work for me through wine and be aware that this is tricky to get working through a virtual machine since it needs to be on the same layer 2 network as the encoder).

Resetting to factory defaults

To reset the username/password to something known, you can either use the IPTV_Control_Center.exe utility and press the "Factory Reset" to the bottom right, assuming the utility detects your encoder.

Or if you know the encoder's IP address you can use telnet:

$ telnet 192.168.1.20 9999
Trying 192.168.1.20...
Connected to 192.168.1.20.
Escape character is '^]'.
==============================
========IPTV TX Server========
==============================
input>list
set_group_id        get_group_id        set_dhcp            get_dhcp           
set_uart_baudrate   get_uart_baudrate   set_static_ip       get_static_ip      
set_mac_address     get_mac_address     get_lan_status      get_hdcp           
get_video_lock      get_ip_config       set_session_key     set_device_name    
get_device_name     set_video_bitrate   get_video_bitrate   set_downscale_mode
get_downscale_mode  set_video_out_mode  get_video_out_mode  set_streaming_mode
get_streaming_mode  get_fw_version      get_company_id      factory_reset      
reboot              list                exit                
input>factory_reset
Processing factory reset!
System will reboot after few seconds!
Connection closed by foreign host.

Configuring

Access the web interface at the encoder's IP address. The username and password will be:

username: admin
password: 123456

You can change whichever settings you like. I only changed the username/password and the device's IP to 192.168.1.20. After you change the IP you have to press the encoder's reset button for the changes to take effect.

To change the destination IP where the encoded stream is sent to a normal unicast IP address you will have manually enter a URL:

http://DEV_IP/dev/info.cgi?action=streaminfo&rtp=on&multicast=on&mcastaddr=DST_IP
e.g.:
http://192.168.1.20/dev/info.cgi?action=streaminfo&rtp=on&multicast=on&mcastaddr=192.168.1.42

Now set your computer's IP to wherever you directed the stream (in the above case 192.168.1.42) and you are ready to receive.

Receiving the stream

You will need a recent ffmpeg, e.g. a statically compiled one from here.

Capture the raw video, encode audio to AAC and save as an FLV file:

ffmpeg -i udp://192.168.1.2:5004 -vcodec copy -codec:a aac -b:a 128k -f flv out.flv

This assumes your computer's IP is 192.168.1.2 and the encoder device is configured to send to that IP (and has an IP on the same subnet).

You should be able to play the video with e.g. VLC or mplayer.

Re-broadcasting to an RTMP server

To re-broadcast the unaltered video simply replace the filename with an rtmp url. For youtube this would look like:

ffmpeg -i udp://192.168.1.2:5004 -vcodec copy -codec:a aac -b:a 128k -f flv out.flv rtmp://a.rtmp.youtube.com/live2/<stream key>

streaming down-converted to 720p

You might want to transcode the video to compress it further before sending. Here's a command for transcoding to 720p 1 mbit/s and sending to youtube with the overrun_nonfatal parameter and an increased fifo_size which should protect a bit against brief service interruptions.

./ffmpeg -i udp://192.168.1.2:5004 -c:v libx264 -x264opts nal-hrd=cbr:force-cfr=1 -minrate 1000k -maxrate 1000k -bufsize 100k -b:v 1000k -vf scale=-1:720 -codec:a aac -b:a 128k -f flv "rtmp://a.rtmp.youtube.com/live2/sbjf-k8q7-phtd-4hag?overrun_nonfatal=1&fifo_size=50000000"
@drosengarden
Copy link

Excellent! Thank you. Your post helped me realize I didn't brick my device with the FW "upgrade" (technically downgrade, I believe, as I was on 20161116 going to 20160427). I was able to discover IP address with Wireshark and follow your instructions to get it back on my normal network.

I have the device "multicasting" to one destination IP, and it is able to pick up using UDP (even though I told the command strong udp=n and rtp=y). Apparently, some of these features are no longer (were they ever?) programmable.

One disappointment is that although the command link suggest that you should be able to change the port (&port=5004), when I did this, the port did not change. I was hoping to change to &port=5005, for example, as I have several of these extender senders that I hoped to stream to the same destination IP.

Any suggestions on a clean and easy solution to pick up the stream of multiple senders at one destination IP? Thanks!

@Juul
Copy link
Author

Juul commented Nov 14, 2020

Hm I don't have any advice but I pinged my friend who might.

@drosengarden
Copy link

Thanks. I'm looking into somehow adding a 2nd IP to the same interface on my PC. I would have to add a total of 5 more (grand total of 6) to the same interface, if possible. Otherwise, changing the port on the sending extender would be cleanest if it could be done.

@Juul
Copy link
Author

Juul commented Nov 14, 2020

If adding a second IP is all you need then that's pretty simple in *nix systems. Look at ip addr add.

@muxlux
Copy link

muxlux commented Nov 14, 2020

i don't recall ever being able to change the port but i think i was able to pickup the different ip addresses with vlc.

i may have time tmrw to dig out my encoders & refresh my memory.

@drosengarden
Copy link

So I've successfully added multiple IPs to my Windows machine. AND I DID IT! I have 2 of my 6 TX Senders (so far) on a "multicast" to a single destination IP address. Each of those IP addresses I just added as additional IPs to my destination device and turned SkipAsSource to TRUE (which means those IP addresses will not be used as any sending sources by any programs on the PC - I will keep them this way to be reserved only for receiving the stream from the devices).

Very cool! I will now proceed to set up the remaining four devices, get them all attached to my network switch, and see if I can have all 6 sources in OBS (the ultimate goal here) using VLC Video Source plug in.

You were a HUGE help in getting me past the "stuck" part of the IP address changing after rolling back to 20160427 - THANK YOU!.

@Juul
Copy link
Author

Juul commented Nov 14, 2020

No problem. Glad it worked :D

@makuser
Copy link

makuser commented Nov 17, 2020

Very cool! I will now proceed to set up the remaining four devices, get them all attached to my network switch, and see if I can have all 6 sources in OBS (the ultimate goal here) using VLC Video Source plug in.

Will you let us know if you managed to do that? ;)

@drosengarden
Copy link

OK - this is a terrible example, but is an example (be sure to sub to our channel . . . just because :) It works and it works well. What you are seeing in this video is the lag of my CPU maxed to 100% from OBS. I'm not sure why that is happening, and it's been happening as of late (even before attaching these LENKENGs as a source). I may have added programs, services, and/or OBS updates are becoming more resource intensive hogs. I can assure you the monitor on OBS was smooth. I also recorded locally and it was smoother, but still with some skipped frames - but again, this is likely due to the limitation of my CPU settings and overload of OBS scenes, sources, and rendering settings.

Don't forget to sub, eh? :)

https://www.youtube.com/watch?v=bGUWV2zbSrM

@muxlux
Copy link

muxlux commented Nov 17, 2020 via email

@drosengarden
Copy link

Thanks!

So, I'm not entirely sure I understand what you mean I should do.

Where would I match the in/out formats to avoid this transcoding?

Also - some of the games did look like the left/right edges are cut, but in Fortnite (the right middle screen) it look like it was filling the full 16:9 ratio (I had the screen captures all at 640x360 on a 1920x1080 canvas).

I'd have to figure out how I can check if I was getting full HD or not.

@muxlux
Copy link

muxlux commented Nov 17, 2020 via email

@Eugenechee51
Copy link

Many thanks!

@fragtion
Copy link

fragtion commented Nov 23, 2022

Has anyone managed to use ffmpeg or similar, to successfully broadcast a h264 stream to the RX / Receiver (lkv373 v3 RX)?

@JanCeuleers
Copy link

In the "buying" section please mention that V3 hardware needs to be purchased; V4 hardware won't work with the firmware you recommend.

@Juul
Copy link
Author

Juul commented Jan 16, 2023

In the "buying" section please mention that V3 hardware needs to be purchased; V4 hardware won't work with the firmware you recommend.

Thanks! I didn't know V4 hardware existed.

@JanCeuleers
Copy link

Do you know of a reliable way to tell the device to stop streaming? I'm trying to avoid network and server load at times when the video stream isn't needed. What I've tried so far is to tell the device to stream to IP address 127.0.0.1, which usually does the job, but which also makes the device prone to lockups from which it only recovers by hard resetting it or power cycling it.

@JanCeuleers
Copy link

Thanks! I didn't know V4 hardware existed.

One change I've spotted is that it has only one PROM chip, so it seems that the firmware for both microcontrollers is now centralised into one PROM chip. So I would guess that one of them is now the master, and downloads firmware to the other. So no wonder that the V3 firmware isn't compatible with V4 hardware.

@Juul
Copy link
Author

Juul commented Feb 2, 2023

Do you know of a reliable way to tell the device to stop streaming?

I don't, sorry. I'd probably just pipe it through a cheap two-port OpenWRT device and toggle firewall rules.

@JanCeuleers
Copy link

Just letting you know that I have created an article on the MythTV wiki that refers to your work.

https://www.mythtv.org/wiki/Recording_from_HDMI

@JanCeuleers
Copy link

I found that I can improve lipsync by telling ffmpeg to subtract 300ms from the presentation time stamps of the audio stream thusly:

ffmpeg -i [etc etc] -filter_complex "asetpts=PTS-0.3/TB" [etc etc]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment