Join multiple GoPro MP4 files to single one

GoPro 'chapters' are footage around 4 GB - The camera starts a new file every ~ 10 minutes. If you have media files with exactly the same codec and codec parameters you can concatenate them quite easily. Fastest way, that I found, is use ffmpeg with concating function, but there is one unnecessary step with mylist.txt, the list of all files, you want to have concatenated.

for f in *.MP4; do echo "file '$PWD/$f'"; done > mylist.txt

If your shell supports process substitution (like Bash and Zsh), you can avoid explicitly creating a list file and do the whole thing in a single line:

ffmpeg -f concat -safe 0 -i <(for f in *.MP4; do echo "file '$PWD/$f'"; done) -c copy output.mp4

Here is also nice bash function, that can be put to your .bash_profile:

function video-concat() {
  ffmpeg -f concat -safe 0 -i <(for f in ${@:1:${#}-1}; do echo "file '$PWD/$f'"; done) -c copy $_

Then you can call video-concat function as follow:

video-concat *.MP4 output.mp3


Display HTML with embed tag

<!DOCTYPE html>
<html lang="en">
  <meta charset="utf-8" />
  <embed type="text/html" id="response" scrolling="no" style="height: 640px; width:100%;">
(async function() {
  const embedResponse = document.getElementById('response');
    try {
      // clean content first     
      embedResponse.setAttribute('src', 'data:text/html;charset=utf-8,');
      const response = await fetch('/api/response',
          method: 'post',
          // accept HTML response
          headers: {
            'Accept': 'application/json, text/plain, */*',
            'Content-Type': 'application/json'
          // sent data if needed
          body: JSON.stringify({data: ''})

      // encode HTML response
      const html = await response.text();
      embedResponse.setAttribute('src', 'data:text/html;charset=utf-8,' + encodeURIComponent(html));

    } catch (e) {
      // catch errors and show them
      embedResponse.setAttribute('src', 'data:text/html;charset=utf-8,' + encodeURIComponent(e));

There is another option, you can display HTML in new window as blob data:

const content = URL.createObjectURL(new Blob([ + overlay || ''], {type: "text/html"}));, "response", `width=640, height=480`).focus();


January 2021

Tools & services

Image hosting


  • Keychron K3 - World's First Hot-Swappable Low Profile Optical Wireless Mechanical Keyboard
  • A2+ Speakers - A2+ premium powered speakers with high-fidelity stereo sound
  • Gibbon AIR - active monitor system with Bluetooth
  • Neumann NDH-20 - premium quality studio headphones
  • Lagoon anc traveller - Wireless headphones with ANC from BeyerDynamic
  • Sony WH-1000XM4 - Wireless Noise-Canceling Headphones form Sony
  • Raspberry Pi Pico - Raspberry Pi Pico is a tiny, fast, and versatile board built using RP2040, a brand new microcontroller chip designed by Raspberry Pi


  • Guestbook - GitHub issue based Guestbook
  • Utteranc - A lightweight comments widget built on GitHub issues.
  • Octomments - Using GitHub issues as a comment plugin.
  • Commento - Embed comments without giving up your privacy.
  • Fast Comments - A comment service that will delight your users and developers.

Earl Grey


  • Primer - Design, build, and create with GitHub’s design system


PHP code speed comparison

function versus(callable $first, callable $second, $repeat = 100000) {
    $f = microtime(true);
    foreach (range(0, $repeat) as $r) call_user_func($first);
    $firstTimer = microtime(true) - $f;
    $s = microtime(true);
    foreach (range(0, $repeat) as $r) call_user_func($second);
    $secondTimer = microtime(true) - $s;

        '%s function is %.2f%% faster (%f vs %f)',
        $firstTimer < $secondTimer ? 'First' : 'Second',
        abs((($firstTimer - $secondTimer) / $firstTimer) * 100),
        $firstTimer, $secondTimer


    function () {
        $str = '!loremipsum';
        return substr($str, 0, 1) === '!';
    function () {
        $str = '!loremipsum';
        return $str[0] === '!';

Will print:

Second function is 36.72% faster (0.142766 vs 0.090349)