<div class="" style="box-sizing: inherit; background-color: #ffffff;">
   <p style="box-sizing: inherit; margin-top: 0.6em; margin-bottom: -0.27em; line-height: 40px;"><font color="#292929" face="sohne, Helvetica Neue, Helvetica, Arial, sans-serif"></font></p>
   <p style="box-sizing: inherit; margin-top: 0.6em; margin-bottom: -0.27em; line-height: 1.5;"><font color="#292929" face="sohne, Helvetica Neue, Helvetica, Arial, sans-serif"><span style="font-family: &quot;맑은 고딕&quot;, &quot;malgun gothic&quot;; font-size: 14px;"><span style="letter-spacing: -0.512px;">camurl="rtsp://admin:admin1357@192.168.0.234/0"<br /></span></span></font><span style="font-family: &quot;맑은 고딕&quot;, &quot;malgun gothic&quot;; font-size: 14px;">videoname=`date +%Y_%m_%d_%H_%M_%S.mkv`</span></p>
   <p style="box-sizing: inherit; margin-top: 0.6em; margin-bottom: -0.27em; line-height: 1.5;"><span style="color: #292929; font-family: &quot;맑은 고딕&quot;, &quot;Malgun Gothic&quot;; font-size: 14px; letter-spacing: -0.512px;">ffmpeg -rtsp_transport tcp -i ${camurl} -vcodec copy -reset_timestamps 1 -t 10 -segment_format mkv -strftime 1 ${vide&nbsp; &nbsp; oname}</span></p>
   <p>&nbsp;</p>
   <hr style="height: 1px; background-color: #999999; border: none;" />
   <p><span style="color: #292929; font-family: sohne, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-size: 32px; letter-spacing: -0.016em;">Saving RTSP Camera Streams with FFmpeg</span></p>
   </div>
<figure class="ec ee hu hv hw hx dy dz paragraph-image" style="box-sizing: inherit; margin: 40px auto 0px; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, Oxygen, Ubuntu, Cantarell, &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, sans-serif; font-size: medium; background-color: #ffffff;">
   <div role="button" tabindex="0" class="hy hz di ia bf ib" style="box-sizing: inherit; width: 680px; position: relative; cursor: zoom-in; z-index: auto; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s;">
      <div class="dy dz ht" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 2074px;"><picture style="box-sizing: inherit;"><source srcset="https://miro.medium.com/max/640/1*A3cMvU_B4UBTvQu3HmweAw.webp 640w, https://miro.medium.com/max/720/1*A3cMvU_B4UBTvQu3HmweAw.webp 720w, https://miro.medium.com/max/750/1*A3cMvU_B4UBTvQu3HmweAw.webp 750w, https://miro.medium.com/max/786/1*A3cMvU_B4UBTvQu3HmweAw.webp 786w, https://miro.medium.com/max/828/1*A3cMvU_B4UBTvQu3HmweAw.webp 828w, https://miro.medium.com/max/1100/1*A3cMvU_B4UBTvQu3HmweAw.webp 1100w, https://miro.medium.com/max/1400/1*A3cMvU_B4UBTvQu3HmweAw.webp 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" style="box-sizing: inherit;" /><source data-testid="og" srcset="https://miro.medium.com/max/640/1*A3cMvU_B4UBTvQu3HmweAw.jpeg 640w, https://miro.medium.com/max/720/1*A3cMvU_B4UBTvQu3HmweAw.jpeg 720w, https://miro.medium.com/max/750/1*A3cMvU_B4UBTvQu3HmweAw.jpeg 750w, https://miro.medium.com/max/786/1*A3cMvU_B4UBTvQu3HmweAw.jpeg 786w, https://miro.medium.com/max/828/1*A3cMvU_B4UBTvQu3HmweAw.jpeg 828w, https://miro.medium.com/max/1100/1*A3cMvU_B4UBTvQu3HmweAw.jpeg 1100w, https://miro.medium.com/max/1400/1*A3cMvU_B4UBTvQu3HmweAw.jpeg 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" style="box-sizing: inherit;" /><img alt="" class="bf ic id c" loading="eager" role="presentation" src="https://miro.medium.com/max/700/1*A3cMvU_B4UBTvQu3HmweAw.jpeg" style="box-sizing: inherit; vertical-align: middle; width: 680px; max-width: 100%; height: auto;" /></picture></div>
      </div>
   <figcaption class="ie if ea dy dz ig ih bd b be z fs" data-selectable-paragraph="" style="box-sizing: inherit; line-height: 20px; font-family: sohne, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-size: 14px; margin-left: auto; margin-right: auto; max-width: 728px; color: #757575; margin-top: 10px; text-align: center;">Photo by&nbsp;<a class="ae ii" href="https://unsplash.com/@speedoshots" rel="noopener ugc nofollow" target="_blank" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">https://unsplash.com/@speedoshots</a></figcaption>
   </figure>
<h1 id="7868" class="ij ik gw bd il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg bi" data-selectable-paragraph="" style="box-sizing: inherit; margin: 3.14em 0px -0.37em; font-family: sohne, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; color: #292929; line-height: 28px; font-size: 22px; background-color: #ffffff;">If you’re just here for the command to copy-paste:</h1>
<pre class="jh ji jj jk ek jl jm jn jo aw jp bi" style="box-sizing: inherit; margin-top: 56px; margin-bottom: 0px; border: none; color: #292929; overflow-x: auto; font-family: source-code-pro, Menlo, Monaco, &quot;Courier New&quot;, Courier, monospace; padding: 20px; border-radius: 0px; background: rgb(242, 242, 242); font-size: medium;"><span id="66f5" class="jq ik gw jm b eu jr js l jt ju" data-selectable-paragraph="" style="box-sizing: inherit; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-top: -0.09em; margin-bottom: -0.09em; white-space: pre-wrap; min-width: fit-content;">ffmpeg -hide_banner -y -loglevel error -rtsp_transport tcp -use_wallclock_as_timestamps 1 -i rtsp://username:password@192.168.1.123:554/stream1 -vcodec copy -acodec copy -f segment -reset_timestamps 1 -segment_time 900 -segment_format mkv -segment_atclocktime 1 -strftime 1 %Y%m%dT%H%M%S.mkv</span></pre>
<p id="5f5e" class="pw-post-body-paragraph jv jw gw jx b jy jz ka kb kc kd ke kf kg kh ki kj kk kl km kn ko kp kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 2em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">I’ve put a fair bit of experimentation into the settings in this command. I’ve included the what and whys below, as well as a camera recommendation for RTSP.</p>
<h2 id="cdc5" class="jq ik gw bd il kt ku kv ip kw kx ky it kg kz la ix kk lb lc jb ko ld le jf lf bi" data-selectable-paragraph="" style="box-sizing: inherit; margin: 2.37em 0px -0.31em; font-family: sohne, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; color: #292929; line-height: 24px; font-size: 20px; background-color: #ffffff;">FFmpeg</h2>
<p id="4fad" class="pw-post-body-paragraph jv jw gw jx b jy lg ka kb kc lh ke kf kg li ki kj kk lj km kn ko lk kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 0.86em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;"><a class="ae ii" href="https://www.ffmpeg.org/" rel="noopener ugc nofollow" target="_blank" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">FFmpeg</a>&nbsp;is an open source software project for handling video, audio, and other multimedia streams using a command-line application.</p>
<figure class="jh ji jj jk ek hx dy dz paragraph-image" style="box-sizing: inherit; margin: 56px auto 0px; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, Oxygen, Ubuntu, Cantarell, &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, sans-serif; font-size: medium; background-color: #ffffff;">
   <div role="button" tabindex="0" class="hy hz di ia bf ib" style="box-sizing: inherit; width: 680px; position: relative; cursor: zoom-in; z-index: auto; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s;">
      <div class="dy dz ll" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1974px;"><picture style="box-sizing: inherit;"><source srcset="https://miro.medium.com/max/640/1*Htn7AetklbAvXNs4txN83w.webp 640w, https://miro.medium.com/max/720/1*Htn7AetklbAvXNs4txN83w.webp 720w, https://miro.medium.com/max/750/1*Htn7AetklbAvXNs4txN83w.webp 750w, https://miro.medium.com/max/786/1*Htn7AetklbAvXNs4txN83w.webp 786w, https://miro.medium.com/max/828/1*Htn7AetklbAvXNs4txN83w.webp 828w, https://miro.medium.com/max/1100/1*Htn7AetklbAvXNs4txN83w.webp 1100w, https://miro.medium.com/max/1400/1*Htn7AetklbAvXNs4txN83w.webp 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" style="box-sizing: inherit;" /><source data-testid="og" srcset="https://miro.medium.com/max/640/1*Htn7AetklbAvXNs4txN83w.jpeg 640w, https://miro.medium.com/max/720/1*Htn7AetklbAvXNs4txN83w.jpeg 720w, https://miro.medium.com/max/750/1*Htn7AetklbAvXNs4txN83w.jpeg 750w, https://miro.medium.com/max/786/1*Htn7AetklbAvXNs4txN83w.jpeg 786w, https://miro.medium.com/max/828/1*Htn7AetklbAvXNs4txN83w.jpeg 828w, https://miro.medium.com/max/1100/1*Htn7AetklbAvXNs4txN83w.jpeg 1100w, https://miro.medium.com/max/1400/1*Htn7AetklbAvXNs4txN83w.jpeg 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" style="box-sizing: inherit;" /><img alt="" class="bf ic id c" loading="lazy" role="presentation" src="https://miro.medium.com/max/700/1*Htn7AetklbAvXNs4txN83w.jpeg" style="box-sizing: inherit; vertical-align: middle; width: 680px; max-width: 100%; height: auto;" /></picture></div>
      </div>
   <figcaption class="ie if ea dy dz ig ih bd b be z fs" data-selectable-paragraph="" style="box-sizing: inherit; line-height: 20px; font-family: sohne, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-size: 14px; margin-left: auto; margin-right: auto; max-width: 728px; color: #757575; margin-top: 10px; text-align: center;">Photo by&nbsp;<a class="ae ii" href="https://unsplash.com/@ikukevk" rel="noopener ugc nofollow" target="_blank" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">https://unsplash.com/@ikukevk</a></figcaption>
   </figure>
<h1 id="5e23" class="ij ik gw bd il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg bi" data-selectable-paragraph="" style="box-sizing: inherit; margin: 3.14em 0px -0.37em; font-family: sohne, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; color: #292929; line-height: 28px; font-size: 22px; background-color: #ffffff;">Breaking Down The Script</h1>
<pre class="jh ji jj jk ek jl jm jn jo aw jp bi" style="box-sizing: inherit; margin-top: 56px; margin-bottom: 0px; border: none; color: #292929; overflow-x: auto; font-family: source-code-pro, Menlo, Monaco, &quot;Courier New&quot;, Courier, monospace; padding: 20px; border-radius: 0px; background: rgb(242, 242, 242); font-size: medium;"><span id="0b81" class="jq ik gw jm b eu jr js l jt ju" data-selectable-paragraph="" style="box-sizing: inherit; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-top: -0.09em; margin-bottom: -0.09em; white-space: pre-wrap; min-width: fit-content;">-hide_banner -y</span></pre>
<p id="8c8f" class="pw-post-body-paragraph jv jw gw jx b jy jz ka kb kc kd ke kf kg kh ki kj kk kl km kn ko kp kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 2em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">This supresses the copyright notice, build options, and library versions from printing to the console.</p>
<pre class="jh ji jj jk ek jl jm jn jo aw jp bi" style="box-sizing: inherit; margin-top: 56px; margin-bottom: 0px; border: none; color: #292929; overflow-x: auto; font-family: source-code-pro, Menlo, Monaco, &quot;Courier New&quot;, Courier, monospace; padding: 20px; border-radius: 0px; background: rgb(242, 242, 242); font-size: medium;"><span id="b090" class="jq ik gw jm b eu jr js l jt ju" data-selectable-paragraph="" style="box-sizing: inherit; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-top: -0.09em; margin-bottom: -0.09em; white-space: pre-wrap; min-width: fit-content;">-loglevel error</span></pre>
<p id="91f6" class="pw-post-body-paragraph jv jw gw jx b jy jz ka kb kc kd ke kf kg kh ki kj kk kl km kn ko kp kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 2em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">I received a lot of warning messages from most RTSP camera streams. We can fix most of these warnings with the other command line options, and I didn’t want these warnings filling up my logs during normal use.</p>
<pre class="jh ji jj jk ek jl jm jn jo aw jp bi" style="box-sizing: inherit; margin-top: 56px; margin-bottom: 0px; border: none; color: #292929; overflow-x: auto; font-family: source-code-pro, Menlo, Monaco, &quot;Courier New&quot;, Courier, monospace; padding: 20px; border-radius: 0px; background: rgb(242, 242, 242); font-size: medium;"><span id="71b7" class="jq ik gw jm b eu jr js l jt ju" data-selectable-paragraph="" style="box-sizing: inherit; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-top: -0.09em; margin-bottom: -0.09em; white-space: pre-wrap; min-width: fit-content;">-rtsp_transport tcp</span></pre>
<p id="207e" class="pw-post-body-paragraph jv jw gw jx b jy jz ka kb kc kd ke kf kg kh ki kj kk kl km kn ko kp kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 2em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">Our options here are TCP or UDP. In my experiments with recording UDP streams, the video files were regularly corrupted. I assume this is due to the non-guaranteed packet delivery or order. I have tried tweaking various FFmpeg settings such as the buffer size, but could not get files saving reliability on UDP. It does provide a good lower-latency, lighter-bandwidth live streaming option though.</p>
<pre class="jh ji jj jk ek jl jm jn jo aw jp bi" style="box-sizing: inherit; margin-top: 56px; margin-bottom: 0px; border: none; color: #292929; overflow-x: auto; font-family: source-code-pro, Menlo, Monaco, &quot;Courier New&quot;, Courier, monospace; padding: 20px; border-radius: 0px; background: rgb(242, 242, 242); font-size: medium;"><span id="5a5a" class="jq ik gw jm b eu jr js l jt ju" data-selectable-paragraph="" style="box-sizing: inherit; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-top: -0.09em; margin-bottom: -0.09em; white-space: pre-wrap; min-width: fit-content;">-use_wallclock_as_timestamps 1</span></pre>
<p id="4bc2" class="pw-post-body-paragraph jv jw gw jx b jy jz ka kb kc kd ke kf kg kh ki kj kk kl km kn ko kp kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 2em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">This rebuilds the timestamps in the video feed. In my experiments with various network cameras this was needed to make the saved videos correctly seek-able. I think this resolves issues with varying framesrates from some network cameras, and streams from some brands not including correct timestamps.</p>
<pre class="jh ji jj jk ek jl jm jn jo aw jp bi" style="box-sizing: inherit; margin-top: 56px; margin-bottom: 0px; border: none; color: #292929; overflow-x: auto; font-family: source-code-pro, Menlo, Monaco, &quot;Courier New&quot;, Courier, monospace; padding: 20px; border-radius: 0px; background: rgb(242, 242, 242); font-size: medium;"><span id="359c" class="jq ik gw jm b eu jr js l jt ju" data-selectable-paragraph="" style="box-sizing: inherit; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-top: -0.09em; margin-bottom: -0.09em; white-space: pre-wrap; min-width: fit-content;">-i rtsp://username:password@192.168.1.123:554/stream1</span></pre>
<p id="4b1e" class="pw-post-body-paragraph jv jw gw jx b jy jz ka kb kc kd ke kf kg kh ki kj kk kl km kn ko kp kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 2em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">This is the address of the RTSP video stream we want to use as the input. Each camera will have a different URL that you can find with an online search. The URL above is for a Tapo C310. If the camera needs a username and password it is prefixed to the IP address.</p>
<pre class="jh ji jj jk ek jl jm jn jo aw jp bi" style="box-sizing: inherit; margin-top: 56px; margin-bottom: 0px; border: none; color: #292929; overflow-x: auto; font-family: source-code-pro, Menlo, Monaco, &quot;Courier New&quot;, Courier, monospace; padding: 20px; border-radius: 0px; background: rgb(242, 242, 242); font-size: medium;"><span id="ff86" class="jq ik gw jm b eu jr js l jt ju" data-selectable-paragraph="" style="box-sizing: inherit; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-top: -0.09em; margin-bottom: -0.09em; white-space: pre-wrap; min-width: fit-content;">-vcodec copy <br style="box-sizing: inherit;" />-acodec copy</span></pre>
<p id="1065" class="pw-post-body-paragraph jv jw gw jx b jy jz ka kb kc kd ke kf kg kh ki kj kk kl km kn ko kp kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 2em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">These parameters tell FFmpeg not to reencode the video or audio streams, and instead just to copy them. This will minimise the CPU usage which is good for recording multiple streams on something like a Raspberry PI. The trade-off is that the video will probably be larger than if re-encoded into a more efficient format. The quality and size of the “copied” video stream files will depend on the specific camera and its settings.</p>
<pre class="jh ji jj jk ek jl jm jn jo aw jp bi" style="box-sizing: inherit; margin-top: 56px; margin-bottom: 0px; border: none; color: #292929; overflow-x: auto; font-family: source-code-pro, Menlo, Monaco, &quot;Courier New&quot;, Courier, monospace; padding: 20px; border-radius: 0px; background: rgb(242, 242, 242); font-size: medium;"><span id="a201" class="jq ik gw jm b eu jr js l jt ju" data-selectable-paragraph="" style="box-sizing: inherit; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-top: -0.09em; margin-bottom: -0.09em; white-space: pre-wrap; min-width: fit-content;">-f segment</span></pre>
<p id="c335" class="pw-post-body-paragraph jv jw gw jx b jy jz ka kb kc kd ke kf kg kh ki kj kk kl km kn ko kp kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 2em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">These next few parameters tell FFmpeg to save the video stream to smaller segment files, instead of writing to one never-ending file.</p>
<pre class="jh ji jj jk ek jl jm jn jo aw jp bi" style="box-sizing: inherit; margin-top: 56px; margin-bottom: 0px; border: none; color: #292929; overflow-x: auto; font-family: source-code-pro, Menlo, Monaco, &quot;Courier New&quot;, Courier, monospace; padding: 20px; border-radius: 0px; background: rgb(242, 242, 242); font-size: medium;"><span id="1135" class="jq ik gw jm b eu jr js l jt ju" data-selectable-paragraph="" style="box-sizing: inherit; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-top: -0.09em; margin-bottom: -0.09em; white-space: pre-wrap; min-width: fit-content;">-reset_timestamps 1</span></pre>
<p id="7037" class="pw-post-body-paragraph jv jw gw jx b jy jz ka kb kc kd ke kf kg kh ki kj kk kl km kn ko kp kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 2em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">This resets the timestamps at the start of each segment file to zero. It was needed to fix problems with video files not being seekable. I assume it was due to the timestamps being saved incorrectly.</p>
<pre class="jh ji jj jk ek jl jm jn jo aw jp bi" style="box-sizing: inherit; margin-top: 56px; margin-bottom: 0px; border: none; color: #292929; overflow-x: auto; font-family: source-code-pro, Menlo, Monaco, &quot;Courier New&quot;, Courier, monospace; padding: 20px; border-radius: 0px; background: rgb(242, 242, 242); font-size: medium;"><span id="6788" class="jq ik gw jm b eu jr js l jt ju" data-selectable-paragraph="" style="box-sizing: inherit; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-top: -0.09em; margin-bottom: -0.09em; white-space: pre-wrap; min-width: fit-content;">-segment_time 900</span></pre>
<p id="eb2f" class="pw-post-body-paragraph jv jw gw jx b jy jz ka kb kc kd ke kf kg kh ki kj kk kl km kn ko kp kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 2em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">This tells FFmpeg that each file should be 15 minutes (900 seconds) long before a new one is started.</p>
<pre class="jh ji jj jk ek jl jm jn jo aw jp bi" style="box-sizing: inherit; margin-top: 56px; margin-bottom: 0px; border: none; color: #292929; overflow-x: auto; font-family: source-code-pro, Menlo, Monaco, &quot;Courier New&quot;, Courier, monospace; padding: 20px; border-radius: 0px; background: rgb(242, 242, 242); font-size: medium;"><span id="3ede" class="jq ik gw jm b eu jr js l jt ju" data-selectable-paragraph="" style="box-sizing: inherit; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-top: -0.09em; margin-bottom: -0.09em; white-space: pre-wrap; min-width: fit-content;">-segment_atclocktime 1 </span></pre>
<p id="b7c9" class="pw-post-body-paragraph jv jw gw jx b jy jz ka kb kc kd ke kf kg kh ki kj kk kl km kn ko kp kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 2em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">This makes FFmpeg start and finish recording files at “round” times, e.g. 09:00, 09:15, 09:30 etc. The start and finish times will not be exactly on the times, since videos must start and stop on keyframes. You can expect the files start/end to be within a few seconds of the round-times though.</p>
<pre class="jh ji jj jk ek jl jm jn jo aw jp bi" style="box-sizing: inherit; margin-top: 56px; margin-bottom: 0px; border: none; color: #292929; overflow-x: auto; font-family: source-code-pro, Menlo, Monaco, &quot;Courier New&quot;, Courier, monospace; padding: 20px; border-radius: 0px; background: rgb(242, 242, 242); font-size: medium;"><span id="5398" class="jq ik gw jm b eu jr js l jt ju" data-selectable-paragraph="" style="box-sizing: inherit; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-top: -0.09em; margin-bottom: -0.09em; white-space: pre-wrap; min-width: fit-content;">-segment_format mkv</span></pre>
<p id="adae" class="pw-post-body-paragraph jv jw gw jx b jy jz ka kb kc kd ke kf kg kh ki kj kk kl km kn ko kp kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 2em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">Save the videos as .mkv files. I chose .mkv over .mp4 due to the increased resilience to corruption .mkv provided. I tried pulling the plug on my cameras while recording streams to simulate someone stealing the camera. The .mkv files recorded right up to the moment the power was cut, whereas .mp4 files often became corrupt and unplayable.</p>
<pre class="jh ji jj jk ek jl jm jn jo aw jp bi" style="box-sizing: inherit; margin-top: 56px; margin-bottom: 0px; border: none; color: #292929; overflow-x: auto; font-family: source-code-pro, Menlo, Monaco, &quot;Courier New&quot;, Courier, monospace; padding: 20px; border-radius: 0px; background: rgb(242, 242, 242); font-size: medium;"><span id="fe0f" class="jq ik gw jm b eu jr js l jt ju" data-selectable-paragraph="" style="box-sizing: inherit; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-top: -0.09em; margin-bottom: -0.09em; white-space: pre-wrap; min-width: fit-content;">-strftime 1 <br style="box-sizing: inherit;" />%Y%m%dT%H%M%S.mkv</span></pre>
<p id="b18a" class="pw-post-body-paragraph jv jw gw jx b jy jz ka kb kc kd ke kf kg kh ki kj kk kl km kn ko kp kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 2em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">This is the naming convention for the video files. The collection of letters and percent signs is a formatting string that tells FFmpeg how to use the date to name this files. We’re using this ISO8601-like format because it allows us to order by the files by date by sorting alphabetically. The video starting at 2022–01–30 21:30:00 will be saved as 20220130T213000.mkv (give or take a few seconds). You can also add a directory before this string to save the videos in a different location to where you’re running the command line. e.g. “C:\Users\you\Videos\front_door\%Y%m%dT%H%M%S.mkv” on Windows.</p>
<h2 id="e2ef" class="jq ik gw bd il kt ku kv ip kw kx ky it kg kz la ix kk lb lc jb ko ld le jf lf bi" data-selectable-paragraph="" style="box-sizing: inherit; margin: 2.37em 0px -0.31em; font-family: sohne, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; color: #292929; line-height: 24px; font-size: 20px; background-color: #ffffff;">Note</h2>
<p id="0a4a" class="pw-post-body-paragraph jv jw gw jx b jy lg ka kb kc lh ke kf kg li ki kj kk lj km kn ko lk kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 0.86em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">On Windows, when I used a lower case “z” in the date formatting string it was parsed to a descriptor like “GMT Summer Time” instead of “+0100”. This is not the behaviour the documentation describes, which is that a capital Z should output the descriptor and a lower case z should output an offset. This didn’t happen when running the command on Linux (i.e. “z” outputs an offset like “+0100”).</p>
<h1 id="6295" class="ij ik gw bd il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg bi" data-selectable-paragraph="" style="box-sizing: inherit; margin: 3.14em 0px -0.37em; font-family: sohne, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; color: #292929; line-height: 28px; font-size: 22px; background-color: #ffffff;">Why am I doing this?</h1>
<p id="0d5b" class="pw-post-body-paragraph jv jw gw jx b jy lg ka kb kc lh ke kf kg li ki kj kk lj km kn ko lk kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 0.86em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">I’ve hacked together a basic Network Video Recorder with a Raspberry PI and an old external HDD. Most security cameras have on-board recording to SD cards, but this presents two problems:<br style="box-sizing: inherit;" />1. If someone takes a security camera the recordings are lost.<br style="box-sizing: inherit;" />2. Most SD cards have quite a limited number of writes before breaking. Smaller SD cards I’ve tried haven’t even lasted a year of recording and overwriting to the card 24/7.</p>
<h1 id="9c65" class="ij ik gw bd il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg bi" data-selectable-paragraph="" style="box-sizing: inherit; margin: 3.14em 0px -0.37em; font-family: sohne, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; color: #292929; line-height: 28px; font-size: 22px; background-color: #ffffff;">Example Code Use / Project</h1>
<p id="3e0f" class="pw-post-body-paragraph jv jw gw jx b jy lg ka kb kc lh ke kf kg li ki kj kk lj km kn ko lk kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 0.86em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">You can find a basic Network Video Recorder that runs on a Raspberry Pi using this script&nbsp;<a class="ae ii" href="https://github.com/TomHumphries/simple-nvr" rel="noopener ugc nofollow" target="_blank" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">here</a>.</p>
<h1 id="83f9" class="ij ik gw bd il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg bi" data-selectable-paragraph="" style="box-sizing: inherit; margin: 3.14em 0px -0.37em; font-family: sohne, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; color: #292929; line-height: 28px; font-size: 22px; background-color: #ffffff;">Which Camera Do I Use?</h1>
<p id="0523" class="pw-post-body-paragraph jv jw gw jx b jy lg ka kb kc lh ke kf kg li ki kj kk lj km kn ko lk kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 0.86em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">I’ve tried 3 different security cameras for saving RTSP steams. I would recommend the&nbsp;<span class="jx gx" style="box-sizing: inherit; font-weight: 700;">Tapo C310</span>&nbsp;as the RTSP video stream is stable, the video quality is decent, and the accompanying app is good for viewing the live stream.</p>
<p id="0178" class="pw-post-body-paragraph jv jw gw jx b jy jz ka kb kc kd ke kf kg kh ki kj kk kl km kn ko kp kq kr ks gp bi" data-selectable-paragraph="" style="box-sizing: inherit; margin-top: 2em; margin-bottom: -0.46em; color: #292929; word-break: break-word; line-height: 32px; letter-spacing: -0.003em; font-family: source-serif-pro, Georgia, Cambria, &quot;Times New Roman&quot;, Times, serif; font-size: 20px; background-color: #ffffff;">I’d love to know if you found this script useful and to hear about any projects it helped you with!</p>