Making a video smaller

A couple of hours ago, i received a video that is 50 frames per second, and compressed in H264, the video was 58MB, and she wanted it less than 15 to send it via email, the video was 1:45 long, so i re-encoded it in H-265 but she had a problem playing it (No codec), so i decided to re-encode it with VP9 (webm).

to arrive at a number less than 10, i needed to be encoding at around 1 MegaBIT per second, now, to do this, I made a 2pass encoding with ffmpeg as follows

ffmpeg -i source.mp4 -c:v libvpx-vp9 -b:v 1M -filter:v fps=25 -pass 1 -an -f null /dev/null && \
ffmpeg -i source.mp4 -c:v libvpx-vp9 -b:v 1M -filter:v fps=25 -pass 2 -c:a libopus out.webm

The first pass collects statistics about the source video in a text log file, the second pass encodes the new video, from the options above, i have taken the frame rate to 25fps (from 50), and instead of defining the crf, i simply told ffmpeg what the biterate I need is, which is 1Mbit per second (Every 8 seconds, 1 MBYTE)

The previous one, H-265 was done with the command

ffmpeg -i source264.mp4 -c:v libx265 -crf 28 -preset fast -c:a aac -b:a 128k  -filter:v fps=25 out265.mp4

the H265 was smaller due to the crf factor used, as well as the lower frame rate

Docker Cheat Sheet

Like the name implies, this is a cheat sheet to quickly find the command you need, they are ordered by the frequency a command is used, or at least what i think is going to be needed more frequently, I have also grouped them by function

The container name in the examples is mycontainer, it is just a name that you will need to replace with your own container name, the container ID here is always 12345abcdef

CommandArgumentsWhat it does
============>Containers – list
docker container lsDisplay running containers
docker container ls -aa: also show containers that are not runningDisplay all containers, running or not
docker psShow running containersPS is the same as LS but older
============>Containers – Run
docker run --name mycontainer -i -t imagename1- The name of the container to run (mycontainer)
2- The i flag indicating you’d like to open an interactive SSH session to the container. The i flag does not close the SSH session even if the container is not attached.
3- The t flag allocates a pseudo-TTY which much be used to run commands interactively.
4- The base image to create the container from (imagename).
Runs the container, and leaves you on a shell prompt that executes commands on that container (As if you have ssh-ed into it)
docker run --name mycontainer -d imagename-d for running the container in the background
docker stop my_containerStop the running container
docker exec -it mycontainer /bin/bash-it flag allows you to run a container in interactive modeIf this doesn’t work, you may not have bash installed, you can try the next command

Gives you access to the shell, much like opening an SSH session to the container
docker exec -it username/mycontainer /bin/sh
ctrl+p followed by ctrl+qDetach from container

Sometimes, accessing a container throght the command line may not be enough, there is a chance you want to access it for file transfer for example, in that case, you want port 22 exposed, and you want to be connected to it like you would connect to a virtual machine

webP is the new PNG

Superior in both Lossless compression, and Lossy compression, webp is the new image format by google

Already supported by all web browsers *(that i have tested it with), webP is indeed a promising format, so let us get to compressing our images

I have a big bunch of bitmaps that my scanner spits out (To avoid lossy jpeg compression the scanner’s driver produces), and i need them converted to lossless webp to save space (the first image I compressed went from 552MB bitmap to 183), that is 33% of the original size

So, under linux, this is how i would convert all BMPs into webp images, I think it is exectly the same on windows

on the command line, the command for compressing one image looks like

cwebp -lossless 00.bmp -o 00.webp

Now, the next step is to run them in a batch, copy the following text into a file and name it with the extension

Installing Hyper-v on a windows 11 Home edition

To install Hyper-v, you typically open the add features menu in windows and add Hyper-v, this works in Windows Pro, but does not work in windows Home

In Windows Home, it is a very simple process

Create a file and name it (hv.bat), mind you, this is the whole name, where bet is the new file extension, make sure you don’t have an hv.bat.txt undreneath (Make sure windows is showing you the extensions)

Now, All you need to do is put the following text in the batch file (hv.bat), then Run it as administrator

     pushd "%~dp0"
     dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum >hv.txt
     for /f %%i in ('findstr /i . hv.txt 2^>nul') do dism /online /norestart /add-package:"%SystemRoot%\servicing\Packages\%%i"
     del hv.txt
     Dism /online /enable-feature /featurename:Microsoft-Hyper-V -All /LimitAccess /ALL
     pause

Once done, the command prompt will ask you whether you would like to restart your computer to apply changes, I would suggest you respond with N (For no) and take your time closing all your applications etc… then restart manually

Right after the restart, hit the windows key on your computer, and type hyper-v, the application should appear and you can run it, it works just like it does on the pro version

Happy computing 😉

Linux find and replace string in multiple files

On windows, you might have been using text editors that search or search&replace within files in a folder, one such tool i have used in windows is “source edit” by Joacim Andersson (Brixoft Software). that text editor does not seem to be maintained any longer as the developer seems to have moved into making games, but there are certainly many other editors that allow you to do the same thing.

On the other hand, on Linux, I don’t need to do that, the basic tools that come with the operating system allow for that, multi gigabyte files can be searched and have certain text replaced at the speed it takes to read them (Without having to open them for editing)

So, let us assume we have a folder with many text files (Including css or js or html or php files for example), to search that folder, we can combine

grep -Ril "text-to-find-here" /path/to/file/

-R (-r) look for files recursively
-l show file names, not the contents that were found
-i ….

Another tool which is better suited for looking in code is ack (ack-grep) which i will come back to cover in this article, and a newer tool that i have never used is

Now, replacing a string inside a file is simple, there is a cool tool called sed

sed -i '/TEXTTOFIND/ s//TEXTTOREPLACEWITH/g' verylargefile.txt

Now, to find all occurances of a string in all the files in a directory and it’s subdirectories, you can use the following command, Mind you, this is always treated as a regular expression, if your string contains a dot or anything else that is part of regular expression syntax, you will need to escape it, to avoid that, check out the sd command below

find -type f -exec sed -i 's/find/replace/g' {} +

{} + invokes the “exec” command with multiple file names at once, instead of once per file

The sd command

the -s flag disables regular expressions, sd and fd have rust crates, apt install fd-find sd

fd --type file --exec sd 'Find' 'Replace'
Or with backup
fd --type file --exec cp {} {}.bk \; --exec sd 'from "react"' 'from "preact"'

-s : No regular expressions

In some cases you can even forget about fd, as sd is now capable of dealing with multiple files
sd -i "\n" "," *.txt

What is YARN and npm

yarn to JavaScript, is what composer is to PHP, a dependency manager, meant to replace npm, but still works with npm

package.json is the file that dictated the dependencies for npm

So, a small comparison of yarn commands (executed in the terminal in the project’s directory which produces a build directory within that directory), the build directory is what you serve the world, in other words, it is what you put in your website’s root directory !

Tasknpmyarn
Create the build directorynpm run buildyarn run build
Update all packagesnpm installyarn (synonyms to yarn install)

Gnome terminal tab title

To tell tabs apart fast, you can give every terminal tab a name, just execute the following line inside that terminal window

echo -ne "\033]0;SOME TITLE HERE\007"

I am doing this on the default gnome terminal in Debian 11/12 (Bullseye/Bookworm), older methods no longer work

You will have to execute this every time in every SSH window to a remote machine, I am looking into a way to making the name permanent !

Does this work with putty on windows?

YES ! I have just tested this with the latest putty (2024-11-02), two and a half years after posting this for terminal in gnome, and I can confidently say it does…

Laravel Tutorial: Blade part 1

The simplest Blade tutorial !

Disambiguation: This tutorial is about Blade, the template engine for Laravel…. I am covering blade on Laravel 9, but I am also taking into account that you might be maintaining code from blade 5 !

Why yet another blade tutorial ? they are all over the place !

long as this tutorial may be, it should be an easy read. no need to memorize stuff or write notes, I am trying to structure it in such a way so that you can effortlessly understand the concept, then come back for that one little syntax you have forgotten very easily.

Simply put, i think blade is a very simple framework that you can complicate if you insist, I think there is an easier way to get someone up and running with blade, a tutorial that compares the Blade way to the traditional way, does not invoke flashy abbreviations before explaining what they mean, and serves you the simplest explanation first… Also one that involves illustrations, shows the different features and explains how they differ and when to use features and why…

I’ll leave the flashy terms and history lessons near the end of the tutorial for completeness, and because they may be useful, but not before you are comfortable with Blade.

Why not a video tutorial

If this gets any attention, I will create a video from it, but I personally prefer reading and looking at illustrations.

What is blade in simple terms ?

Traditionally, when creating a website in PHP, your HTML is mostly in the same PHP files that provide the functionality ! blade is here to help you separate your HTML content from your PHP functionality…

Blade is a special folder in your Laravel project where you add those PHP files that contain your HTML*, plain old folder where you simply separate those files from the rest of your code. files in that folder enjoy extra functionality provided by blade that takes out the inconveniences of separating the HTML.

in your Laravel project, that folder is usually /resources/views, blade PHP files end in .blade.php, for example, mytheme.blade.php

* HTML And JSON if you are also writing an API…. and whatever you normally add to your HTML such as inline CSS and inline JS

Isn’t Separating my HTML into it’s own files a lot more work ?

Well, that is what blade is for, it provides tools to make this simple and easy

Traditionally, if you wanted to separate the HTML from the rest of your code, you would create PHP files with the HTML in them, and use PHP’s include function to show them… or embed the HTML inside functions that are in separate files, and send the data to those functions (or classes) and print what is returned…

That works, and blade is more or less the same thing, but as you proceed with Blade, you will see how blade resolves many inconveniences that this method comes with.

Let’s get down to it !

Setup Laravel on your system

First, I am assuming you have already setup Laravel and created a new project, if not, please take a look here (/2022/09/07/laravel-tutorial-laravel-setup/) for instructions on how to do that !

Create a couple of dummy routes

Now that you have such a setup, We will need to add a couple of routes (URL definitions), don’t concern yourself with what they are or what they mean, they are covered in the next section, they are just here to enable us to learn blade, routes is in a totally different place, all you need to learn for now that those two routes are invoked when you visit the URLs they define, and they pass the variables you see in them to the blade templates

Routes are added to the /routes/web.php file, so open that file and add the following at the end of it, now you have two URLs that work, the home page, and a /test page





First Blade File: plain HTML and nothing more

Now, let us create our first BLADE file, let us call it example.blade.php, and in that file, we will simply add an HTML page with nothing to do with blade specific features, Just that page that will display whether you use the home page (the first route from above), or the /test route that you see in the other route !

—————–

Unorganized content to be incorporated into the tutorial

If you stick to a couple of rules, it is compiled into PHP code and cached, so it is really fast !
Asset helpers
Layouts (extends, Yeild, section, show)
Partials
Components: includes, arrays vs collections {{$var->entry}}, props, <x-cards>,

BLADE  is inspired by .NET’s Razor engine.

Allows you to use PHP code inside (@php directive), but you should not need to, and you should not unless you have to
(If you feel a need, you are misplacing your code)

If you come from Symfony, you can use Twig through Twig-bridge !

Syntax

1- Echo
{{ $variable }} is equivalent to <?= htmlentities( $variable ) ?>

Sometimes you may need to echo handlebar notation into the output, so you can simply use an @ before the above notation

@{{ $variable }} will output {{ $variable }} (Without the @)

or, if you want things to just print as they are, you can use the @verbatim directive !

{!! $variable !!} is equivalent to <?= $variable ?>


{{ $variable }} = <?= htmlentities( $variable ) ?> 
{!! $variable !!} = <?= $variable ?>
{{-- comment is here --}}



self explanatory blade directives

if elseif else endif (endif is the closing after all of them)

@unless and @endunless = equivilent to if(!cond)

@for, @foreach, and @while (endfor endforeach enwhile)

@forelse and @endforelse = ForElse is a ForEach loop, but with extra handling for empty array.

@forelse ($talks as $talk)
	{{ $talk->title }} ({{ $talk->length }} minutes)<br>
@empty
	No talks this day.
@endforelse

-----------------------------------------------------------
Defining Sections with @section/@show and @yield

yeilds first param is the section name, it's second is A DEFAULT VALUE

instead of yeild, if you want an entier block as a default fallback, you can use

@section('footerScripts')
<script src="app.js"></script>
@show

In this @section .... @show, if we want to append to the default value above, we should include @parent in the child template extending this, otherwise, the contents above will be overwritten !

Note that The @show is in the parent section, shows in place, while the @section and @endsection are in the child !

the section show is both defining a default and doing so in such a way that its default contents will be available to its children, through @parent

to use all of the above... assuming the template is at resources/views/layouts/master.blade.php
@extends('layouts.master') {{-- Each file should only extend one other file, and the @extends call should be the first line of the file --}}

@section('title', 'Dashboard')

@section('content')
     Welcome to your application dashboard!
@endsection

@section('footerScripts')
@parent
     <script src="dashboard.js"></script>
@endsection
-----------------------------------
partials



------------------------------------------------
1: creating a folder called images under public !

---------------------------------------------------

Method 1: @yeild

put the header and footer in one file called layout.blade.php in one peice (empty doc)

within the template, you put in 

@yield('content)

in other layout components, you use the extends directive, and make the content inside
 
 @extends(layout)
 
 @section('content')

whatever needed to appear in the theme, the content that is labeled content just like in yeild

@endsection

partials are added with include, so if you put the thing in the partials directory, the convention is that a file starts with underscore as a partial, _hero.blade.php

include('partials._hero)

Method 2: making the layout a component

---------------

in routes, read on route model binding, instead of passing $id to the inner function and route specification, we pass an object of type listing (The model listing) to the inner function, and in the route specification, the word /blah/{listing}, we  it allows us to just 

Audio Video Libraries at home DLNA etc

This is basically a comparison of free sofwtare that you can install on your NAS or headless linux machine, I am using Debian Bullseye, but that is besides the point

To run webm files (VP9) through miniDLNA, all you need to do is rename the file !

My atom PC (D525) is not capable of transcoding on the fly, so i keep it, and i wrote a script to execute the following command for webm video files (and any other unsupported file) by browsing to the file in the web browser, then clicking on it, a simple script but explaining how to install it is going to take some times with permissions and server config, so i will probably be posting it online and explaining in a different post when i have the time

ffmpeg -y -i output.webm -c:v libx265 -b:v 2600k -x265-params pass=1 -an -f null /dev/null && \
ffmpeg -i input -c:v libx265 -b:v 2600k -x265-params pass=2 -c:a aac -b:a 128k TEMP_OUTPUT.mp4

the most popular of the bunch is MiniDLNA, it does not transcode, and on openWRT it does not even serve video, so it is a good option when you have a PC storing the files, and you don’t need transcoding on the fly ! for some devices that are capable of running VP9 like modern 4K TVs,all you need to do is rename the file !

Universal Media Server : Universal Media Server is a DLNA-compliant UPnP Media Server. It was originally based on PS3 Media Server by shagrath.

OSMC

Streama: Self hosted streaming media server.

Gerbera: Free UPnP media server based on MediaTomb