<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Ave&#39;s tech notes</title>
    <link>https://wf.lavatech.top/aves-tech-notes/</link>
    <description></description>
    <pubDate>Sun, 12 Apr 2026 10:30:23 +0000</pubDate>
    <item>
      <title>eMRTD data quirks</title>
      <link>https://wf.lavatech.top/aves-tech-notes/emrtd-data-quirks</link>
      <description>&lt;![CDATA[This is a list of quirks I spotted on eMRTDs that I&#39;m posting to try and help out anyone else who is trying to parse them. It&#39;s a list I will continue updating, probably.&#xA;&#xA;As I&#39;ve spotted these while implementing hf emrtd set of commands on Proxmark3, they&#39;re all fixed there.&#xA;&#xA;Last updated: 2025-01-30&#xA;&#xA;!--more--&#xA;&#xA;Authentication protocol&#xA;&#xA;Really old Belgian passports don&#39;t enforce any authentication.&#xA;German Personalausweises, even those issued before 2018, enforce PACE. Those issued before August 2021 do not contain the chip inside logo.&#xA;German Aufenhaltstitels, even those issued before 2018, enforce PACE. They do have the chip inside icon, and had them while enforcing PACE all the way back to 2015.&#xA;&#xA;MRZ and EFDG1 (TD3 - Passport Size)&#xA;&#xA;For the optional field, some countries use a number even if it is empty (all &lt;), and some use &lt;. (CH etc)&#xA;Germany uses D for country code (D&lt;&lt; on MRZ) instead of DEU. This is the only instance where a country code deviates from ISO 3166-1 alpha-3. (This is also documented on ICAO 9303 p3 Edition 7 and German Passport Act Law.)&#xA;&#xA;Note: ICAO 9303 p3 Edition 8 does not properly reflect this, and this is likely a drafting error. I have contacted ICAO about this.&#xA;&#xA;MRZ and EFDG1 (TD1 - ID Size)&#xA;&#xA;Old (2017) Turkish IDs use German-style ascii-ification while new ones (2018 and after) don&#39;t. (2017: OEZDIL, 2018 and after: OZDIL)&#xA;Turkish IDs have one preceding &lt; before the ID number on optional field (&lt;1234568902&lt;&lt;&lt;).&#xA;Germany uses D for country code (D&lt;&lt; on MRZ) instead of DEU. This is the only instance where a country code deviates from ISO 3166-1 alpha-3. (This is also documented on ICAO 9303 p3 and German Passport Act Law.)&#xA;&#xA;Document type codes&#xA;&#xA;First two characters of MRZ are for document type. No one can decide what exactly they want to use, especially for residence permits. Here&#39;s what I found for residence permits based on going through PRADO for EU+EEA+Schengen members. I will go through IDs and Passports at some point, but I don&#39;t expect them to differ much (except Italy, because why not).&#xA;&#xA;P = Passport, I = ID, IP = Passport Card&#xA;C&lt;= ID (Italy)&#xA;ID = ID, but sometimes Residence Permit (Belgium, Denmark, Poland 2014)&#xA;AD = Residence Permit (Croatia)&#xA;AR = Residence Permit (Germany, Austria, Lithuania 2022, Slovenia, Switzerland)&#xA;CR = Residence Permit (Italy, Sweden EU-related)&#xA;IB = Residence Permit, Document Certifying Permanent Residence (Poland 2021)&#xA;IW = Residence Permit, Certificate Of Registration Of Stay (Poland 2021)&#xA;IK = Residence Permit, Permanent Residence Card (Poland 2021)&#xA;IE = Residence Permit (Poland 2014, Norway Family Members)&#xA;IO = Residence Permit (Poland 2014)&#xA;IF = Residence Permit, Residence Card (Poland 2014+2021)&#xA;IZ = Residence Permit (Poland 2014)&#xA;IR = Residence Permit (France, Belgium, Cyprus, Czechia, Spain, Finland, Greece, Hungary, Ireland, Lithuania 2012, Luxembourg, Latvia, Malta, Poland 2011+2020, Portugal, Romania, Slovakia, Sweden, Norway, Estonia 2020)&#xA;IT = Residence Permit (Lithuania 2020, Poland 2014)&#xA;RP = Residence Permit (Estonia 2011)&#xA;RT = Residence Permit (Iceland)&#xA;&#xA;EFDG11&#xA;&#xA;Belgian (and french?) passports have some tags with len=0, specifically on localized names (5F 0Eh) and alternative names (5F 0Fh under A0h).&#xA;Hungarian passports have non-localized names (5F 0Fh) on EFDG11.&#xA;Turkish IDs and Passports (pre and post NVI) have full dates of birth (5F 2Bh) as ASCII.&#xA;Belgian and French passports have full dates of birth (5F 2Bh) as bytes.&#xA;&#xA;EFDG12&#xA;&#xA;Turkish IDs and Passports (pre and post NVI) have issuance dates (5F 26h) as ASCII (Example: 20201231 or 50 48 50 48 49 50 51 49h).&#xA;Belgian and French passports have issuance dates (5F 26h) as bytes (Example: 20 20 12 31h).&#xA;&#xA;EFSOD&#xA;&#xA;Turkish IDs and Passports don&#39;t include 05 00h at the end of hash algorithm (on descriptors such as 06 09 60 86 48 01 65 03 04 02 01 05 00h for SHA256), while some do.&#xA;USA Passports use 80h for field length of the main EFSOD sequence, declaring the size as having an indefinite length as per BER.&#xA;Different countries have different times between the document issuance date and certificate start date, between the document expiry date and the certificate end date. Netherlands seems to be 3 and 6 days respectively for Netherlands, and 45 and 45 days respectively for Turkey.&#xA;&#xA;EFCardAccess&#xA;&#xA;BSI TR-03110-3 says on section A.1.1.7.: &#34;The string urlCardInfo SHALL define the location that provides the most recent CardInfo file [5] for the respective ICC type and version&#34;.&#xA;&#xA;This in turn relates to BSI TR-03112-4 (section 4) and CEN/TS 15480-4. It&#39;s to improve interoperability among EU IDs.&#xA;&#xA;On German eIDs and electronic residence permits (probably German Unionsbürger eIDs too), this is set to http://bsi.bund.de/cif/npa.xml, which is 404 at the time of writing (2025), I have contacted BSI about this.]]&gt;</description>
      <content:encoded><![CDATA[<p>This is a list of quirks I spotted on eMRTDs that I&#39;m posting to try and help out anyone else who is trying to parse them. It&#39;s a list I will continue updating, probably.</p>

<p>As I&#39;ve spotted these while implementing <code>hf emrtd</code> set of commands on Proxmark3, they&#39;re all fixed there.</p>

<p>Last updated: 2025-01-30</p>



<h2 id="authentication-protocol" id="authentication-protocol">Authentication protocol</h2>
<ul><li>Really old Belgian passports don&#39;t enforce any authentication.</li>
<li>German Personalausweises, even those issued before 2018, enforce PACE. Those issued before August 2021 do not contain the chip inside logo.</li>
<li>German Aufenhaltstitels, even those issued before 2018, enforce PACE. They do have the chip inside icon, and had them while enforcing PACE all the way back to 2015.</li></ul>

<h2 id="mrz-and-ef-dg1-td3-passport-size" id="mrz-and-ef-dg1-td3-passport-size">MRZ and EF_DG1 (TD3 – Passport Size)</h2>

<p><img src="https://elixi.re/t/lk6ytypqk.png" alt=""></p>
<ul><li>For the optional field, some countries use a number even if it is empty (all <code>&lt;</code>), and some use <code>&lt;</code>. (CH etc)</li>
<li>Germany uses <code>D</code> for country code (<code>D&lt;&lt;</code> on MRZ) instead of <code>DEU</code>. This is the only instance where a country code deviates from ISO 3166-1 alpha-3. (This is also documented on ICAO 9303 p3 Edition 7 and <a href="https://www.gesetze-im-internet.de/englisch_pa_g/englisch_pa_g.html" rel="nofollow">German Passport Act Law</a>.)</li></ul>

<p>Note: ICAO 9303 p3 Edition 8 does not properly reflect this, and this is likely a drafting error. I have contacted ICAO about this.</p>

<h2 id="mrz-and-ef-dg1-td1-id-size" id="mrz-and-ef-dg1-td1-id-size">MRZ and EF_DG1 (TD1 – ID Size)</h2>

<p><img src="https://elixi.re/t/lhainnxbg.png" alt=""></p>
<ul><li>Old (2017) Turkish IDs use German-style ascii-ification while new ones (2018 and after) don&#39;t. (2017: <code>OEZDIL</code>, 2018 and after: <code>OZDIL</code>)</li>
<li>Turkish IDs have one preceding <code>&lt;</code> before the ID number on optional field (<code>&lt;1234568902&lt;&lt;&lt;</code>).</li>
<li>Germany uses <code>D</code> for country code (<code>D&lt;&lt;</code> on MRZ) instead of <code>DEU</code>. This is the only instance where a country code deviates from ISO 3166-1 alpha-3. (This is also documented on ICAO 9303 p3 and <a href="https://www.gesetze-im-internet.de/englisch_pa_g/englisch_pa_g.html" rel="nofollow">German Passport Act Law</a>.)</li></ul>

<h3 id="document-type-codes" id="document-type-codes">Document type codes</h3>

<p>First two characters of MRZ are for document type. No one can decide what exactly they want to use, especially for residence permits. Here&#39;s what I found for residence permits based on going through PRADO for EU+EEA+Schengen members. I will go through IDs and Passports at some point, but I don&#39;t expect them to differ much (except Italy, because why not).</p>
<ul><li><code>P</code> = Passport, <code>I</code> = ID, <code>IP</code> = Passport Card</li>
<li><code>C&lt;</code>= ID (Italy)</li>
<li><code>ID</code> = ID, but sometimes Residence Permit (Belgium, Denmark, Poland 2014)</li>
<li><code>AD</code> = Residence Permit (Croatia)</li>
<li><code>AR</code> = Residence Permit (Germany, Austria, Lithuania 2022, Slovenia, Switzerland)</li>
<li><code>CR</code> = Residence Permit (Italy, Sweden EU-related)</li>
<li><code>IB</code> = Residence Permit, Document Certifying Permanent Residence (Poland 2021)</li>
<li><code>IW</code> = Residence Permit, Certificate Of Registration Of Stay (Poland 2021)</li>
<li><code>IK</code> = Residence Permit, Permanent Residence Card (Poland 2021)</li>
<li><code>IE</code> = Residence Permit (Poland 2014, Norway Family Members)</li>
<li><code>IO</code> = Residence Permit (Poland 2014)</li>
<li><code>IF</code> = Residence Permit, Residence Card (Poland 2014+2021)</li>
<li><code>IZ</code> = Residence Permit (Poland 2014)</li>
<li><code>IR</code> = Residence Permit (France, Belgium, Cyprus, Czechia, Spain, Finland, Greece, Hungary, Ireland, Lithuania 2012, Luxembourg, Latvia, Malta, Poland 2011+2020, Portugal, Romania, Slovakia, Sweden, Norway, Estonia 2020)</li>
<li><code>IT</code> = Residence Permit (Lithuania 2020, Poland 2014)</li>
<li><code>RP</code> = Residence Permit (Estonia 2011)</li>
<li><code>RT</code> = Residence Permit (Iceland)</li></ul>

<h2 id="ef-dg11" id="ef-dg11">EF_DG11</h2>
<ul><li>Belgian (and french?) passports have some tags with len=0, specifically on localized names (<code>5F 0E</code>h) and alternative names (<code>5F 0F</code>h under <code>A0</code>h).</li>
<li>Hungarian passports have non-localized names (<code>5F 0F</code>h) on EF_DG11.</li>
<li>Turkish IDs and Passports (pre and post NVI) have full dates of birth (<code>5F 2B</code>h) as ASCII.</li>
<li>Belgian and French passports have full dates of birth (<code>5F 2B</code>h) as bytes.</li></ul>

<h2 id="ef-dg12" id="ef-dg12">EF_DG12</h2>
<ul><li>Turkish IDs and Passports (pre and post NVI) have issuance dates (<code>5F 26</code>h) as ASCII (Example: <code>20201231</code> or <code>50 48 50 48 49 50 51 49</code>h).</li>
<li>Belgian and French passports have issuance dates (<code>5F 26</code>h) as bytes (Example: <code>20 20 12 31</code>h).</li></ul>

<h2 id="ef-sod" id="ef-sod">EF_SOD</h2>
<ul><li>Turkish IDs and Passports <em>don&#39;t</em> include <code>05 00</code>h at the end of hash algorithm (on descriptors such as <code>06 09 60 86 48 01 65 03 04 02 01 05 00</code>h for SHA256), while some do.</li>
<li>USA Passports use <code>80</code>h for field length of the main EF_SOD sequence, declaring the size as having an indefinite length as per BER.</li>
<li>Different countries have different times between the document issuance date and certificate start date, between the document expiry date and the certificate end date. Netherlands seems to be 3 and 6 days respectively for Netherlands, and 45 and 45 days respectively for Turkey.</li></ul>

<h2 id="ef-cardaccess" id="ef-cardaccess">EF_CardAccess</h2>

<p>BSI TR-03110-3 says on section A.1.1.7.: “The string urlCardInfo SHALL define the location that provides the most recent CardInfo file [5] for the respective ICC type and version”.</p>

<p>This in turn relates to BSI TR-03112-4 (section 4) and CEN/TS 15480-4. It&#39;s to improve interoperability among EU IDs.</p>

<p>On German eIDs and electronic residence permits (probably German Unionsbürger eIDs too), this is set to <a href="http://bsi.bund.de/cif/npa.xml" rel="nofollow">http://bsi.bund.de/cif/npa.xml</a>, which is 404 at the time of writing (2025), I have contacted BSI about this.</p>
]]></content:encoded>
      <guid>https://wf.lavatech.top/aves-tech-notes/emrtd-data-quirks</guid>
      <pubDate>Wed, 23 Dec 2020 19:03:53 +0000</pubDate>
    </item>
    <item>
      <title>The nightmare that is Lottie to GIF conversion</title>
      <link>https://wf.lavatech.top/aves-tech-notes/the-nightmare-that-is-lottie-to-gif-conversion</link>
      <description>&lt;![CDATA[Future edit:&#xA;&#xA;I was informed that rlottie exists (which is used by Telegram and Discord): https://github.com/Samsung/rlottie&#xA;&#xA;It comes with a built-in GIF converter called lottie2gif, but that does not support transparency.&#xA;&#xA;!--more--&#xA;&#xA;I ended up making a (shitty) tool called LFE based on that that, which does the job of extracting each frame as PNGs with transparency. You can then replace the puppeteer-lottie-cli steps to equivalents with lfe.&#xA;&#xA;I&#39;ve run benchmarks of converting 30 files (alongside some other processing), and it ended up getting me over 3x speedups.&#xA;&#xA;Before:&#xA;&#xA;real    6m10.508s&#xA;user    2m3.647s&#xA;sys     0m19.909s&#xA;&#xA;After:&#xA;&#xA;real    1m59.302s&#xA;user    1m56.607s&#xA;sys     0m5.522s&#xA;&#xA;(2020-12-04)&#xA;&#xA;---&#xA;&#xA;This is a blog post intended to explore the current options out there regarding Lottie-  GIF/APNG conversions and go into what I personally ended up doing.&#xA;&#xA;Wait, what is a &#34;Lottie&#34; again?&#xA;&#xA;So, this is a little convoluted, but bear with me.&#xA;&#xA;&#34;Bodymovin&#34; is a project created by Hernan Torrisi in 2015 that allows people to export After Effects projects as special JSON files, and originally, to use them on web.&#xA;&#xA;Lottie seems like it was originally a project by airbnb introduced around early 2017 to bring facemovin to more platforms , but it seems like at some point facemovin became &#34;Lottie-Web&#34;, though it seems like it&#39;s still maintained by Hernan Torrisi.&#xA;&#xA;Lottie is used by a number of large companies. Discord and Telegram recently started using Lottie for their animated stickers. (Though it&#39;s worth noting that Telegram actually uses a fork)&#xA;&#xA;I personally dislike it. Sure, it may be smaller than an APNG, but it also makes my CPU a lot sadder than one, especially when there&#39;s several on the screen at once.&#xA;&#xA;The options out there right now&#xA;&#xA;https://gitlab.com/mattbas/python-lottie&#xA;https://github.com/transitive-bullshit/puppeteer-lottie + https://github.com/transitive-bullshit/puppeteer-lottie-cli&#xA;https://lottiefiles.com/lottie-to-gif/convert&#xA;&#xA;python-lottie&#xA;&#xA;When I first tested python-lottie, it crashed when trying to convert images:&#xA;&#xA;...&#xA;&#xA;They corrected this bug since then, but it still is a little buggy for converting to GIFs:&#xA;&#xA;It needs work on the real world lottie files I tested (like the one above), but it is still quite promising. If you&#39;re reading this far into the future, you might want to try that before you deal with the messy conversion I talk about doing in this blog post.&#xA;&#xA;puppeteer-lottie(-cli)&#xA;&#xA;puppeteer-lottie-cli seemed a lot more promising as it ran a headless browser (and a lot less desirable as it&#39;s much heavier as a result), but outputs were... buggy, especially on parts with transparency:&#xA;&#xA;Lottiefiles.com converter&#xA;&#xA;The lottiefiles.com converter kept popping up here and there and people seemed to be rather happy about it, but it provided no API.&#xA;&#xA;However, this got me wondering... how does that tick behind the scenes?&#xA;&#xA;The deep dive&#xA;&#xA;So, the first thing I ended up doing was searching &#34;Lottiefiles github&#34; to see if their website source code was public, and while it wasn&#39;t...&#xA;&#xA;One of their forks gave me a really good pointer: https://github.com/LottieFiles/puppeteer-lottie&#xA;&#xA;I suddenly realized that puppeteer-lottie had the potential to give me what I need, and started taking a look at the changes of this fork of puppeteer-lottie.&#xA;&#xA;Not much was added, just a way to grab specific frames (and a fix for that).&#xA;&#xA;I got the idea of just extracting frames and going off of those, and then stumbled upon this issue asking for APNG support. What&#39;s more interesting, however, was the fact that the issue body included a way of extracting each frame separately, which isn&#39;t something I realized I could do before.&#xA;&#xA;I quickly did that, and took on the task of converting it into a GIF myself.&#xA;&#xA;Not a lot interesting happened there, but after some fiddling with tools, I ended up with a pretty good way of converting Lotties to GIFs.&#xA;&#xA;how.png&#xA;&#xA;The way I currently convert lotties to GIFs is first extracting them into each separate frame (with a fixed size):&#xA;&#xA;puppeteer-lottie -i &#34;infilename.json&#34; -o &#34;frame-%d.png&#34; --width 500&#xA;&#xA;Then looking at the framerate inside the lottie file (&#34;fr&#34; field in the json), and converting it to an intermediary GIF with ffmpeg...&#xA;&#xA;ffmpeg -y -framerate &#34;frameratefromjson&#34; -i &#34;frame-%d.png&#34; -filter_complex &#34;0:v] fps=50,split [a;a] palettegen [p];[b paletteuse&#34; &#34;intermediary.gif&#34;&#xA;&#xA;And finally, using imagemagick to do a -dispose Background pass for it to render properly everywhere..&#xA;&#xA;convert -dispose Background &#34;intermediary.gif&#34; &#34;final.gif&#34;&#xA;&#xA;This does sadly get rid of transparency, but it also gets rid of all the glitches:&#xA;&#xA;And so, that&#39;s it! The best way of converting Lotties to GIFs at the moment, at least in my opinion.&#xA;&#xA;Notes&#xA;&#xA;: I&#39;m not entirely sure about when exactly Lottie popped up, and the official blog post does not include a date, but the file upload date is 01/2017. The second blog post has a cover image upload date of 08/2017, and refers to Lottie&#39;s release as &#34;6 months ago&#34;.]]&gt;</description>
      <content:encoded><![CDATA[<p><strong>Future edit</strong>:</p>

<p>I was informed that rlottie exists (which is used by <a href="https://github.com/TelegramMessenger/rlottie" rel="nofollow">Telegram</a> and <a href="https://github.com/discord/rlottie" rel="nofollow">Discord</a>): <a href="https://github.com/Samsung/rlottie" rel="nofollow">https://github.com/Samsung/rlottie</a></p>

<p>It comes with a built-in GIF converter called <code>lottie2gif</code>, but that does not support transparency.</p>



<p>I ended up making a (shitty) tool called <a href="https://gitdab.com/distok/LFE" rel="nofollow">LFE</a> based on that that, which does the job of extracting each frame as PNGs with transparency. You can then replace the <code>puppeteer-lottie-cli</code> steps to equivalents with <code>lfe</code>.</p>

<p>I&#39;ve run benchmarks of converting 30 files (alongside some other processing), and it ended up getting me over 3x speedups.</p>

<p>Before:</p>

<pre><code>real    6m10.508s
user    2m3.647s
sys     0m19.909s
</code></pre>

<p>After:</p>

<pre><code>real    1m59.302s
user    1m56.607s
sys     0m5.522s
</code></pre>

<p>(2020-12-04)</p>

<hr>

<p><em>This is a blog post intended to explore the current options out there regarding Lottie-&gt;GIF/APNG conversions and go into what I personally ended up doing.</em></p>

<h2 id="wait-what-is-a-lottie-again" id="wait-what-is-a-lottie-again">Wait, what is a “Lottie” again?</h2>

<p>So, this is a little convoluted, but bear with me.</p>

<p>“Bodymovin” is a project created by <a href="https://github.com/bodymovin" rel="nofollow">Hernan Torrisi</a> in 2015 that allows people to export After Effects projects as special JSON files, and originally, to use them on web.</p>

<p>Lottie seems like it was originally a project by airbnb introduced around early 2017<a href="#notes" rel="nofollow">*</a> to <a href="https://airbnb.design/introducing-lottie/" rel="nofollow">bring facemovin to more platforms</a> , but it seems like at some point facemovin became “Lottie-Web”, though it seems like it&#39;s still maintained by Hernan Torrisi.</p>

<p>Lottie is used by a number of large companies. Discord and Telegram recently started using Lottie for their animated stickers. (Though it&#39;s worth noting that <a href="https://github.com/TelegramMessenger/bodymovin-extension" rel="nofollow">Telegram actually uses a fork</a>)</p>

<p>I personally dislike it. Sure, it may be smaller than an APNG, but it also makes my CPU a lot sadder than one, especially when there&#39;s several on the screen at once.</p>

<h2 id="the-options-out-there-right-now" id="the-options-out-there-right-now">The options out there right now</h2>
<ul><li><a href="https://gitlab.com/mattbas/python-lottie" rel="nofollow">https://gitlab.com/mattbas/python-lottie</a></li>
<li><a href="https://github.com/transitive-bullshit/puppeteer-lottie" rel="nofollow">https://github.com/transitive-bullshit/puppeteer-lottie</a> + <a href="https://github.com/transitive-bullshit/puppeteer-lottie-cli" rel="nofollow">https://github.com/transitive-bullshit/puppeteer-lottie-cli</a></li>
<li><a href="https://lottiefiles.com/lottie-to-gif/convert" rel="nofollow">https://lottiefiles.com/lottie-to-gif/convert</a></li></ul>

<h3 id="python-lottie" id="python-lottie">python-lottie</h3>

<p>When I first tested python-lottie, it crashed when trying to convert images:</p>

<p><img src="https://elixi.re/i/nn15c55g.png" alt=""></p>

<p>...</p>

<p><img src="https://elixi.re/i/05srpyw4.png" alt=""></p>

<p>They corrected this bug since then, but it still is a little buggy for converting to GIFs:</p>

<p><img src="https://elixi.re/i/ru40k8oc.gif" alt=""></p>

<p>It needs work on the real world lottie files I tested (like the one above), but it is still quite promising. If you&#39;re reading this far into the future, you might want to try that before you deal with the messy conversion I talk about doing in this blog post.</p>

<h3 id="puppeteer-lottie-cli" id="puppeteer-lottie-cli">puppeteer-lottie(-cli)</h3>

<p>puppeteer-lottie-cli seemed a lot more promising as it ran a headless browser (and a lot less desirable as it&#39;s much heavier as a result), but outputs were... buggy, especially on parts with transparency:</p>

<p><img src="https://elixi.re/i/89nckfa4.gif" alt=""></p>

<h3 id="lottiefiles-com-converter" id="lottiefiles-com-converter">Lottiefiles.com converter</h3>

<p>The lottiefiles.com converter kept popping up <a href="https://stackoverflow.com/a/61813794/3286892" rel="nofollow">here and there</a> and people seemed to be rather happy about it, but it provided no API.</p>

<p>However, this got me wondering... how does that tick behind the scenes?</p>

<h2 id="the-deep-dive" id="the-deep-dive">The deep dive</h2>

<p>So, the first thing I ended up doing was searching “Lottiefiles github” to see if their website source code was public, and while it wasn&#39;t...</p>

<p>One of their forks gave me a really good pointer: <a href="https://github.com/LottieFiles/puppeteer-lottie" rel="nofollow">https://github.com/LottieFiles/puppeteer-lottie</a></p>

<p>I suddenly realized that puppeteer-lottie had the potential to give me what I need, and started taking a look at the changes of this fork of puppeteer-lottie.</p>

<p>Not much was added, just <a href="https://github.com/LottieFiles/puppeteer-lottie/commit/167322be57894ef2247823d0322b5e9ab02e1166" rel="nofollow">a way to grab specific frames</a> (and <a href="https://github.com/LottieFiles/puppeteer-lottie/commit/89b6ce3728c10d53a0b1a4d7de34d9da07c95d3f" rel="nofollow">a fix for that</a>).</p>

<p>I got the idea of just extracting frames and going off of those, and then stumbled upon <a href="https://github.com/transitive-bullshit/puppeteer-lottie-cli/issues/15" rel="nofollow">this issue</a> asking for APNG support. What&#39;s more interesting, however, was the fact that the issue body included a way of extracting each frame separately, which isn&#39;t something I realized I could do before.</p>

<p>I quickly did that, and took on the task of converting it into a GIF myself.</p>

<p>Not a lot interesting happened there, but after some fiddling with tools, I ended up with a pretty good way of converting Lotties to GIFs.</p>

<h2 id="how-png-https-elixi-re-i-how-png" id="how-png-https-elixi-re-i-how-png"><a href="https://elixi.re/i/how.png" rel="nofollow">how.png</a></h2>

<p>The way I currently convert lotties to GIFs is first extracting them into each separate frame (with a fixed size):</p>

<pre><code class="language-bash">puppeteer-lottie -i &#34;infilename.json&#34; -o &#34;frame-%d.png&#34; --width 500
</code></pre>

<p>Then looking at the framerate inside the lottie file (“fr” field in the json), and converting it to an intermediary GIF with ffmpeg...</p>

<pre><code class="language-bash">ffmpeg -y -framerate &#34;frameratefromjson&#34; -i &#34;frame-%d.png&#34; -filter_complex &#34;[0:v] fps=50,split [a][b];[a] palettegen [p];[b][p] paletteuse&#34; &#34;intermediary.gif&#34;
</code></pre>

<p>And finally, using imagemagick to do a <code>-dispose Background</code> pass for it to render properly everywhere..</p>

<pre><code class="language-bash">convert -dispose Background &#34;intermediary.gif&#34; &#34;final.gif&#34;
</code></pre>

<p>This does sadly get rid of transparency, but it also gets rid of all the glitches:</p>

<p><img src="https://elixi.re/i/88wqzpeu.gif" alt=""></p>

<p>And so, that&#39;s it! The best way of converting Lotties to GIFs at the moment, at least in my opinion.</p>

<h2 id="notes" id="notes">Notes</h2>

<p>*: I&#39;m not entirely sure about when exactly Lottie popped up, and the <a href="https://airbnb.design/introducing-lottie/" rel="nofollow">official blog post</a> does not include a date, but the file upload date is 01/2017. <a href="https://airbnb.design/the-future-of-lottie/" rel="nofollow">The second blog post</a> has a cover image upload date of 08/2017, and refers to Lottie&#39;s release as “6 months ago”.</p>
]]></content:encoded>
      <guid>https://wf.lavatech.top/aves-tech-notes/the-nightmare-that-is-lottie-to-gif-conversion</guid>
      <pubDate>Fri, 27 Nov 2020 23:44:10 +0000</pubDate>
    </item>
    <item>
      <title>Converting custom ringtones and adding them to Cisco VOIP SIP phones in 2020 with an ffmpeg one-liner</title>
      <link>https://wf.lavatech.top/aves-tech-notes/converting-custom-ringtones-and-adding-them-to-cisco-voip-sip-phones-in-2020</link>
      <description>&lt;![CDATA[So, I&#39;ve spent some of my free time in the last 2 days working on LasagnaTel, Lasagna Ltd&#39;s internal phone network, and did some small improvements. One of the changes I wanted to also do was fixing DTMF tones (to only have them inband).&#xA;&#xA;Over the last couple months, I&#39;ve been thinking on and off wondering if my specific cisco phone supports custom ringtones ever since I saw linuxgemini set their ringtone to Nokia Arabic Ringtone, but never really bothered with it, but...&#xA;&#xA;!--more--&#xA;&#xA;While I was trying to edit the config files to fix the DTMF issue, I saw a file called Ringtones.xml on my tftp server from the base set of files I used from an internet resource months ago, and decided to take a look. It had two &#34;custom&#34; ringtones in it (&#34;custom&#34;, as they were the default tunes I believe, but the files were hosted on the server, and weren&#39;t on the phone itself), and when I opened the ringtone menu on the phone, those were displayed, and when I hit play, those did play.&#xA;&#xA;So I ended up trying to add that again.&#xA;&#xA;Just like everything else with these damn phones though, resource was sparse. I ended up not finding too many resources, but with technical information (on what I need to convert my files to) from linuxgemini and this ancient cisco document (archive.lavatech.top, archive.org) and some other information on The Internets™, I was able to figure out how to convert files:&#xA;&#xA;ffmpeg -i in.wav -t 00:00:20.0 -ar 8000 -ac 1 -f mulaw out.raw&#xA;&#xA;As you can see, I&#39;m cutting the files to their first 20 seconds, as that&#39;s the limit. Any longer, and it errors. That&#39;s the thing that gave me the most trouble.&#xA;&#xA;After that, all I had to do was copying it to the tftp server root, adding it to the Ringlist.xml:&#xA;&#xA;CiscoIPPhoneRingList&#xA;  Ring&#xA;    DisplayNameCTU 24/DisplayName&#xA;    FileNameCTU24.raw/FileName&#xA;  /Ring&#xA;  Ring&#xA;    DisplayNameOld Telephone/DisplayName&#xA;    FileNameOldTelephone.raw/FileName&#xA;  /Ring&#xA;  Ring&#xA;    DisplayNameSteins;Gate/DisplayName&#xA;    FileNamesgperfectloop3.raw/FileName&#xA;  /Ring&#xA;  Ring&#xA;    DisplayNameNokia Arabic/DisplayName&#xA;    FileNamenokia-arabic.raw/FileName&#xA;  /Ring&#xA;/CiscoIPPhoneRingList&#xA;&#xA;and re-opening the ringtone menu on the phone. It does take a couple seconds for it to load, and even more seconds for it to download the ringtone the first time you hit play, but it ended up working perfectly once it downloaded it once.&#xA;&#xA;Here&#39;s a video demonstration:&#xA;&#xA;iframe width=&#34;560&#34; height=&#34;315&#34; src=&#34;https://www.youtube.com/embed/b5_t0UydAGs&#34; frameborder=&#34;0&#34; allow=&#34;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&#34; allowfullscreen/iframe&#xA;&#xA;Anyhow, that now works! Enjoy your enterprise shitposting!]]&gt;</description>
      <content:encoded><![CDATA[<p>So, I&#39;ve spent some of my free time in the last 2 days working on LasagnaTel, Lasagna Ltd&#39;s internal phone network, and did some small improvements. One of the changes I wanted to also do was fixing DTMF tones (to only have them inband).</p>

<p>Over the last couple months, I&#39;ve been thinking on and off wondering if my specific cisco phone supports custom ringtones ever since I saw linuxgemini set their ringtone to Nokia Arabic Ringtone, but never really bothered with it, but...</p>



<p>While I was trying to edit the config files to fix the DTMF issue, I saw a file called <code>Ringtones.xml</code> on my tftp server from the base set of files I used from an internet resource months ago, and decided to take a look. It had two “custom” ringtones in it (“custom”, as they were the default tunes I believe, but the files were hosted on the server, and weren&#39;t on the phone itself), and when I opened the ringtone menu on the phone, those were displayed, and when I hit play, those did play.</p>

<p>So I ended up trying to add that again.</p>

<p>Just like everything else with these damn phones though, resource was sparse. I ended up not finding too many resources, but with technical information (on what I need to convert my files to) from linuxgemini and <a href="https://www.cisco.com/c/en/us/td/docs/voice_ip_comm/cucm/admin/10_5_2/ccmfeat/CUCM_BK_C3A84B33_00_cucm-feature-configuration-guide_1052/CUCM_BK_C3A84B33_00_cucm-feature-configuration-guide_chapter_0101011.pdf" rel="nofollow">this ancient cisco document</a> (<a href="https://archive.lavatech.top/archive/1586290010/www.cisco.com/c/en/us/td/docs/voice_ip_comm/cucm/admin/10_5_2/ccmfeat/CUCM_BK_C3A84B33_00_cucm-feature-configuration-guide_1052/CUCM_BK_C3A84B33_00_cucm-feature-configuration-guide_chapter_0101011.pdf" rel="nofollow">archive.lavatech.top</a>, <a href="https://archive.org/details/CiscoCustomPhoneRings" rel="nofollow">archive.org</a>) and some other information on The Internets™, I was able to figure out how to convert files:</p>

<p><code>ffmpeg -i in.wav -t 00:00:20.0 -ar 8000 -ac 1 -f mulaw out.raw</code></p>

<p>As you can see, I&#39;m cutting the files to their first 20 seconds, as that&#39;s the limit. Any longer, and it errors. That&#39;s the thing that gave me the most trouble.</p>

<p>After that, all I had to do was copying it to the tftp server root, adding it to the <code>Ringlist.xml</code>:</p>

<pre><code class="language-xml">&lt;CiscoIPPhoneRingList&gt;
  &lt;Ring&gt;
    &lt;DisplayName&gt;CTU 24&lt;/DisplayName&gt;
    &lt;FileName&gt;CTU_24.raw&lt;/FileName&gt;
  &lt;/Ring&gt;
  &lt;Ring&gt;
    &lt;DisplayName&gt;Old Telephone&lt;/DisplayName&gt;
    &lt;FileName&gt;Old_Telephone.raw&lt;/FileName&gt;
  &lt;/Ring&gt;
  &lt;Ring&gt;
    &lt;DisplayName&gt;Steins;Gate&lt;/DisplayName&gt;
    &lt;FileName&gt;sgperfectloop3.raw&lt;/FileName&gt;
  &lt;/Ring&gt;
  &lt;Ring&gt;
    &lt;DisplayName&gt;Nokia Arabic&lt;/DisplayName&gt;
    &lt;FileName&gt;nokia-arabic.raw&lt;/FileName&gt;
  &lt;/Ring&gt;
&lt;/CiscoIPPhoneRingList&gt;
</code></pre>

<p>and re-opening the ringtone menu on the phone. It does take a couple seconds for it to load, and even more seconds for it to download the ringtone the first time you hit play, but it ended up working perfectly once it downloaded it once.</p>

<p>Here&#39;s a video demonstration:</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/b5_t0UydAGs" frameborder="0" allowfullscreen=""></iframe>

<p>Anyhow, that now works! Enjoy your enterprise shitposting!</p>
]]></content:encoded>
      <guid>https://wf.lavatech.top/aves-tech-notes/converting-custom-ringtones-and-adding-them-to-cisco-voip-sip-phones-in-2020</guid>
      <pubDate>Tue, 07 Apr 2020 20:08:41 +0000</pubDate>
    </item>
    <item>
      <title>Quick post: Using Scaleway C14 Cold Storage with rclone</title>
      <link>https://wf.lavatech.top/aves-tech-notes/quick-post-using-scaleway-c14-cold-storage-with-rclone</link>
      <description>&lt;![CDATA[I&#39;ve been looking for a cold storage solution to use with LavaTech backups for some while now, and was planning to use online.net C14 (now C14 Classic). Well, they just re-released it under Scaleway, and I&#39;ve decided to take on the task of getting cold storage working.&#xA;&#xA;I use rclone for a lot of purposes, and for the task at hand, it&#39;s what I&#39;ll be using to move data from Backblaze B2 hot storage to C14 cold storage.&#xA;&#xA;!--more--&#xA;&#xA;As C14 in rclone is still C14 classic, and as Scaleway C14 implement an S3-like API (it&#39;s not a standard or a protocol as they claim here), I decided to get it working.&#xA;&#xA;Instructions or whatever&#xA;&#xA;Get an API Key from the credentials page&#xA;Edit ~/.config/rclone/rclone.conf and add this (replace access key with your actual key, same for secret key. Change all instances of fr-par to nl-ams if you want to use the AMS region):&#xA;&#xA;[c14-cold]&#xA;type = s3&#xA;provider = Other&#xA;envauth = false&#xA;accesskeyid = access key&#xA;secretaccesskey = secret key&#xA;region = fr-par&#xA;endpoint = https://s3.fr-par.scw.cloud&#xA;locationconstraint = fr-par&#xA;acl = private&#xA;bucketacl = private&#xA;chunksize = 25M&#xA;uploadconcurrency = 100&#xA;storageclass = GLACIER&#xA;&#xA;Save and exit. After this, you can verify that it works by creating a bucket on desktop and then running a command like rclone copy testfile c14-cold:/bucketname and then checking the UI:&#xA;&#xA;Copied file on c14 website&#xA;&#xA;Ps. This uploads directly to Cold Storage without requiring any moving from the UI. If you want to change that, remove the storage_class = GLACIER line from config.]]&gt;</description>
      <content:encoded><![CDATA[<p>I&#39;ve been looking for a cold storage solution to use with <a href="https://lavatech.top" rel="nofollow">LavaTech</a> backups for some while now, and was planning to use online.net C14 (now C14 Classic). <a href="https://www.scaleway.com/en/c14-cold-storage/" rel="nofollow">Well, they just re-released it under Scaleway,</a> and I&#39;ve decided to take on the task of getting cold storage working.</p>

<p>I use rclone for a lot of purposes, and for the task at hand, it&#39;s what I&#39;ll be using to move data from Backblaze B2 hot storage to C14 cold storage.</p>



<p>As C14 in rclone is still C14 classic, and as Scaleway C14 implement an S3-like API (it&#39;s not a standard or a protocol as they claim <a href="https://www.scaleway.com/en/docs/object-storage-feature/" rel="nofollow">here</a>), I decided to get it working.</p>

<h2 id="instructions-or-whatever" id="instructions-or-whatever">Instructions or whatever</h2>
<ul><li>Get an API Key <a href="https://console.scaleway.com/account/credentials" rel="nofollow">from the credentials page</a></li>
<li>Edit <code>~/.config/rclone/rclone.conf</code> and add this (replace <code>&lt;access key&gt;</code> with your actual key, same for secret key. Change all instances of <code>fr-par</code> to <code>nl-ams</code> if you want to use the AMS region):</li></ul>

<pre><code>[c14-cold]
type = s3
provider = Other
env_auth = false
access_key_id = &lt;access key&gt;
secret_access_key = &lt;secret key&gt;
region = fr-par
endpoint = https://s3.fr-par.scw.cloud
location_constraint = fr-par
acl = private
bucket_acl = private
chunk_size = 25M
upload_concurrency = 100
storage_class = GLACIER
</code></pre>
<ul><li>Save and exit. After this, you can verify that it works by creating a bucket on desktop and then running a command like <code>rclone copy testfile c14-cold:/bucketname</code> and then checking the UI:</li></ul>

<p><img src="https://elixi.re/t/l9d9yepzr.png" alt="Copied file on c14 website"></p>

<p>Ps. This uploads directly to Cold Storage without requiring any moving from the UI. If you want to change that, remove the <code>storage_class = GLACIER</code> line from config.</p>
]]></content:encoded>
      <guid>https://wf.lavatech.top/aves-tech-notes/quick-post-using-scaleway-c14-cold-storage-with-rclone</guid>
      <pubDate>Fri, 28 Feb 2020 08:47:34 +0000</pubDate>
    </item>
  </channel>
</rss>