Béton brut

Szybkie życie

2020-03-21

W Internecie bulgocze mem o tym, jak to w czasach zarazy mądrzy ludzie dokonali wielkich czynów i jakie ważne dzieła wyprodukowali. Oczywiście, jak w każdym inspirational porn pomijane są pewne fakty. Na ten przykład twórcy wspaniałych rzeczy nie wdzierali się na intelektualną scenę, a byli na niej już od dawna. Albo to, że nie musieli się w większości przejmować czynszem, zamkniętą szkołą, ani też doświadczać pierwszy raz zdalnej pracy.

Ja celuję dużo niżej. Każdemu jego dzieło w miarę możliwości.

Znudzony i niechętny pracy kręciłem się tu i tam, szukając ciekawego zajęcia. Wyciągnąłem stare numery „Młodego Technika”. Przeczytałem kawałek tekstu o tym jak działają świece zapłonowe. Nie było ognia w moim sercu. Wyciągnąłem Tołstoja, ale na pierwszej stronie było od razu pięć długich, dwuczłonowych rosyjskich nazwisk i wiedziałem, że nie ma szans żebym się odnalazł w tym bez tablicy korkowej i czerwonych sznurków do utworzenia relacji pomiędzy bohaterami historii.

Zastanawiałem się jak wygląda miasto. Od tygodnia wyszedłem z domu trzy razy. Na 5 minut. Dokupić alkoholu i jajek. Jajka jem na śniadanie, alkohol na kolację. Te dumania przypomniały mi o zapomnianej dziś instytucji „publicznych webcamów”. Kiedyś były bardzo popularne, ludzie oglądali obce miasta, kurze fermy, małpy, psy i co jeszcze komu wpadło do głowy. Wpisałem więc frazę w wyszukiwarkę i po chwili widziałem swoją okolicę. Popatrzyłem chwilę jak pan chodzi z miejsca w miejsce, zaparkował samochód, a później odjechał. Pan, śledzony nieustępliwie przez śmieciarkę na światłach, opróżniał kubły. Świat istniał, choć nie wyglądał ciekawie.

Pomyślałem, że mógłbym sobie rzucić to wideo na mały, dziesięciocalowy telewizorek, który stoi w kącie mojego biurka i zabawia mnie wyświetlając anime z lat 80 kiedy pracuję. Stworzyłbym sobie wirtualne okno na ulicę.

Ostatecznie, gdzieś tam pod spodem, jest pewnie jakiś strumień wideo, który można zawinąć.

Poszedłem sprawdzić i oczywiście, jest jakiś. Po pierwsze lista M3U, po drugie powtarzający się cykl fragmentów wideo. Dla testu skopiowałem jeden z linków i podałem do wget. Coś się ściągnęło. mplayer odtworzył 2 sekund wideo z kamery. OK, czyli to tak działa. Wideo jest serwowane w tej serii plików i po osiągnięciu ostatniego, 92 fragmentu, lista zawraca do pierwszego, oznaczonego 42.

Dobra, a czy da się je jakoś seryjnie ściągnąć? Znaczy, na pewno się da, ale tak żebym potem mógł coś z tym zrobić? Otworzyłem nową powłokę terminala i wydałem klasyczne zaklęcie mkdir, git init, vi.

Wpierw wymyśliłem bardzo skomplikowany sposób pobierania tego, z wątkami, sprawdzaniem ETag i kto wie, co jeszcze. A potem uznałem, że głupia metoda jest równie dobra, a doprowadzi mnie do sukcesu szybciej.

Czyli tak:

  1. Wezmę wszystkie kawałki klipów w momencie odpalenia
  2. Zapiszę je sobie na boku
  3. Zobaczę ile czasu mi to zajęło i odejmę od maksymalnej długości wszystkich klipów
  4. go to 1
import requests # klient HTTP
from time import sleep # chcemy pauzować

# wpisany na twardo adres z którego będę pobierał informacje
URL = 'https://cdn-3-go.toya.net.pl:8081/kamery/lodz_piotrkowskaschillera_0{}.ts'

# formad do zapisywania, index poprzedzony dopełnieniem 12 zer
OUTPUT = 'output/{:012}_frame.mpg'

""" Żeby się było łatwiej kręcić, wartości [42…91] w liście """
frames = range(42, 92)

idx = 0
while True:
    # Cała lista otwarzania ma (92-42)*2 sekund 
    rotation_time = len(frames) * 2

    #Kiedy zaczynamy proces
    start_time = datetime.now()

    for frame in frames:
        print("Grabing {}".format(frame))
        # Klasyczny HTTP GET / i zapisanie pliku docelowego
        response = requests.get(URL.format(frame))
        if response.status_code == 200:
            with open(OUTPUT.format(idx), 'wb') as f:
                f.write(response.content)
            idx = idx + 1
    # Jak przelecieliśmy wszystkie ramki to czekamy resztę sekund, aż 
    # się wszystkie podmienią
    after_downloading = datetime.now()
    remaining_seconds = rotation_time - int((after_downloading - start_time).total_seconds())
    print("Clips fetched, sleeping for {}".format(remaining_seconds))
    # …i do łóżka
    sleep(remaining_seconds)

Udało się za pierwszym razem. Pokombinowałem jeszcze z nazwami i takimi tam, ale wyglądało na to, że całość ściągnęła się bez problemu. No dobra, ale co z tym teraz zrobić? Chwilowo nie miałem pomysłu, więc sklonowałem repozytorium na lodówkową RaspberryPi i pozwoliłem się jej kręcić, naciągnąć mi nieco danych.

Minął czas, a ja wymyśliłem. Zrobię tzw. timelapse czyli przyśpieszone wideo z źródłowych fragmentów. Mam w vimwiki całą stronę poświęconą rozmaitym zaklęciom, którymi można przymuszać ffmpeg do robienia fantastycznych rzeczy.

Kiedyś spędziłem wieczór na brzegu zalewu żeby zamienić 6 minutowy filmik z zachodu słońca w taki, który byłby ustabilizowany, krótszy i jeszcze miał muzykę. Wyzwanie: tylko przy użyciu połączenia SSH do domu. Wyszło OK, ale nie spektakularnie.

Nie było sensu zaprzęgać do tego Pythona, wsadziłem całość w prosty skrypt Basha. 1

#!/bin/bash

# Wczytaj z katalogu output wszystkie pliki *.mpg
for file in output/*.mpg ; do
    # Weź obecną nazwę, utnij ją przy kropce, dodaj png
    new_file=`echo $file | cut -d. -f1`.png
    echo $new_file
    # Weź pierwszą klatkę animacji i zapisz pod nową nazwą
    ffmpeg -i $file -vf "select=eq(n\,0)" -vframes 1 $new_file
done

# Zakoduj nowopowstałe klatki w mp4/h264 żeby się przeglądarki nie czepiały
ffmpeg -pattern_type glob -i 'output/*.png'  -an -vcodec libx264 -pix_fmt yuv420p -profile:v baseline -level 3 out.mp4

Po kilku testach postanowiłem, że osiągnąłem znośny efekt (mimo kilku momentów w których uzyskałem duplikaty serii klatek. Mogłem usunąć to post factum ale jak mówił Bob Ross, “There are no mistakes, just happy accidents“), wysłałem wszystko na RaspberryPi i postanowiłem dać się całości kręcić przez noc.

Wysłałem jeszcze e-mail do mojego przyjaciela Łukasza żebrząc o jakiś utwór muzyczny z mojej ulubionej płyty jego projektu, Coffee Sounds. Na moje szczęście zgodził się, za co chcę mu jeszcze raz podziękować.

Wstałem o piątej, zebrałem 17200 klatek i oto przed Wami efekt bezcelowej, nocnej dłubaniny. Łódź, Piotrkowska, Pasaż Schillera. Od 22:30 do 8:00.

  • :15 zaczyna padać deszcz, ulice się świecą odbitym światłem latarni
  • :37 „Do Poloneza? Ale Panie Władzo, ja nie tańczę”
  • 3:15 wschód słońca

Te, zdecydowanie zbyt rzadkie, momemty w moim życiu gdy zamieniam „czy da się?” w „da się” przy pomocy śliny, mchu i oglądania problemu przez palce sprawiają mi zawsze najwięcej radości.

Polecam Wam zaprzęgać komputery do bezużytecznej, kreatywnej pracy. Komputer jako odpalarka do przeglądarki to takie marnotrastwo nieomal nieograniczonej mocy.

Czas szybciej płynie, gdy dłubiesz. Lokatorzy więzień próbujący wykonać podkop też Wam to powiedzą.


  1. Potem trochę pozmieniałem rzeczy, całość dostępna jest w repozytorium git