Skip to content

Instantly share code, notes, and snippets.

@pgaskin
Last active July 28, 2025 02:10
Show Gist options
  • Save pgaskin/8a286615e6c62ec5bc5084bc40f2b1fa to your computer and use it in GitHub Desktop.
Save pgaskin/8a286615e6c62ec5bc5084bc40f2b1fa to your computer and use it in GitHub Desktop.
TP-Link Tapo C100 notes

TP-Link Tapo C100

Overview

I've tried v4.20 and v5.0 hardware revisions.

The v5.0 ones seem a bit more responsive in general, though it's unclear if it's due to firmware or hardware. The v5.0 one does talk out loud when setting it up.

For both versions, recent firmware updates have significantly improved the reliability.

The image quality is decent, and the frame rate and resolution are adjustable. The night vision is decent. There is a slight warping of the image, but it's not noticeable except in the edges.

The speakers are irritating to hear, and the microphone is very low quality and quiet. The noise levels are okay though.

The stand/feet are stable and grippy.

The field of view and image quality is much better than the C200. I do not recommend the C200 unless you must have PTZ.

Overall, I strongly recommend the C100 as long as you don't care about audio and you have sufficient Wi-Fi capacity for the cameras.

Stream

The /stream1 RTSP endpoint has the high-quality stream, and the /stream2 has a downsized one. The codec settings are decent, and result in relatively small file sizes (they could be a bit smaller though). The latency is relatively low (1-2s) Configured with 1080p/15fps:

/stream1 (HW v4.20 @ FW v1.4.0)
  Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x1080, 14.25 fps, 15 tbr, 90k tbn
  Stream #0:1: Audio: pcm_alaw, 8000 Hz, mono, s16, 64 kb/s
/stream1 (HW v5.0 @ FW v1.2.4)
  Stream #0:0: Video: h264 (High), yuv420p(progressive), 1920x1080, 15 fps, 15 tbr, 90k tbn
  Stream #0:1: Audio: pcm_alaw, 8000 Hz, mono, s16, 64 kb/s
/stream2 (HW v4.20 @ FW v1.4.0)
  Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 640x360, 14.25 fps, 15 tbr, 90k tbn
  Stream #0:1: Audio: pcm_alaw, 8000 Hz, mono, s16, 64 kb/s
/stream2 (HW v5.0 @ FW v1.2.4)
  Stream #0:0: Video: h264 (High), yuv420p(progressive), 1280x720, 15 fps, 30 tbr, 90k tbn
  Stream #0:1: Audio: pcm_alaw, 8000 Hz, mono, s16, 64 kb/s

It is capable of multiple simultaneous streams. I've tried with 4 concurrent ones (one in the app, and three over RTSP).

The Wi-Fi connection is 802.11n (72.2 Mbps), and relatively stable. The low latency and consistent ping times are a bit impressive given the cheapness of the camera. The stream is stable and hasn't dropped or glitched for me yet.

The logo can be removed from the stream in the app, and the timezone can be set in the app under "Device Info" (it doesn't look like a button at first, but it is). You can also safely turn off all detections and notifications in the app without affecting the stream.

At 1080p/15fps, the stream produces around 150-250 (v4.20) and 250-550 (v5.0) MB/hour.

Setup

The device boots relatively quickly (5-10s).

I haven't tested how good it is at reconnecting to dropped Wi-Fi yet.

During the initial setup, the network you connect it to needs to have internet access. If it fails to acquire a DHCP lease and/or connect to the cloud services, the light will be solid orange. The first part of the setup is done in the app, and it's best to do this as quickly as possible (the device name can be changed later) or the app sometimes forgets that the camera exists. After the initial setup, the device's private IP is given to the app through the cloud, and the app attempts to connect to it through that IP (it doesn't need to be on the same L2 segment, but it does need to be L3 routable).

Note that on the v5.0 hardware with the factory firmware, I had trouble connecting it to the network. After configuring Wi-Fi in the app, it would reboot, then fail to acquire a DHCP release (it was sending discovers and receiving offers, but not accepting any). The light was orange, and the camera disappeared from the app. Looking at a packet capture, it was attempting to resolve 192.168.0.1 as 192.168.0.10 via ARP. Note that 192.168.0.10 is the default IP for TP-Link cameras. I added 192.168.0.1 as a secondary gateway IP, with a route for 192.168.0.10 from my primary network, and the camera connected to the cloud successfully and reappeared in the app. It still didn't acquire a proper IP though, so I just configured a static one. I haven't tried going through this process again after a firmware update.

After the initial setup and the first reboot, internet can be blocked without any adverse effects. Note that if the IP changes, it needs to be connected to the cloud to tell the app the new IP. If you use firewall rules to control this, it should pick up the internet connectivity within half a minute or so of disabling the firewall rule.

At some point, I might try to reverse-engineer the setup process to make it possible to set it up and configure it offline without the app or the cloud. I might try to figure out the firmware updates too.

Frigate

The camera works well with Frigate, especially after v0.16.0.

go2rtc:
  streams:
    c1_hi:
      - rtsp://USER:PASSWORD@IP:554/stream1
      - ffmpeg:c1_hi#audio=aac # transcode audio to aac so recording works
    c1_lo:
      - rtsp://USER:PASSWORD@IP:554/stream2
cameras:
  c1:
    enabled: true
    ffmpeg:
      output_args:
        record: preset-record-generic-audio-copy
      inputs:
        - path: rtsp://127.0.0.1:8554/c1_hi?video&audio=aac
          input_args: preset-rtsp-restream
          roles:
            - record
        - path: rtsp://127.0.0.1:8554/c1_lo
          input_args: preset-rtsp-restream
          roles:
            - detect
            - audio
    live:
      streams:
        Low: c1_lo
        High: c1_hi

If you want to record in low quality, you can put the record role in the other one, but you'll need to swap around the ?video&audio=aac and the corresponding transcoded go2rtc stream.

During my initial setup in Frigate v0.15.2, I ran into a few bugs:

  • If you don't transcode the audio to aac, it will silently fail to record and will output corrupt segments.
  • If you change the video format partway through the day, seeking will fail.
  • If there are corrupt segments or changes in the format in the current day, the recorded historical stream may seem to infinitely load when seeking.
  • The review tab doesn't work properly until there are is at least one previous day of recordings (it will load infinitely otherwise).

Everything works well after getting through the initial complications.

I'm not using the two-way audio, but for that, I believe you'd need to add a go2rtc stream using the tapo protocol, and configure the live streams to use that, at least for audio.

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