Programming

Awalnya mau gantiin cctv yg sebelumnya pake webcam nyolok di notebook, baca2 sekilas (gak detil) tentang Raspberry Pi + camera module, dan mutusin untuk upgrade cctv di rumah pake raspberry pi. Pas dapet hibahan langsung nyoba2, ternyata gak semudah di notebook biasa, dan waktu nyoba ambil foto pake ‘raspistill’ kok lambat banget, agak susah deh kalo begini.

Pas nyari2 info masang motion di raspberry pi kok jadi repot (padahal yg saya baca itu artikel lama) dan nemu katanya biar bisa live streaming yg cepat (kalo pake yg raspivid delaynya agak lama) pake RPi Cam Web Interface yang ternyata waktu installnya masang Apache2, PHP 7 dan Motion (untuk webserver dan php kalo gak salah ada pilihannya mau yg mana yg diinstall).

Sesudah itu saya pake Web Interfacenya untuk ngontrol. Dari situ saya bisa liat live stream dari kameranya dan ada beberapa aksi yang bisa saya lakukan: rekam video, still image, timelapse, motion detection dan stop camera. Karena terbiasa pake motion dengan motion detectionnya, saya langsung aja tes dan ternyata hasilnya agak mengecewakan karena kalo saya liat motion detectionnya kurang responsif, begitu saya ubek2 ternyata ada parameter frame rate untuk motion detection cuma 2 fps, yg anehnya kalo saya ganti dan simpan selalu gak kesimpen. Efek sampingnya adalah motion detection yang kurang sensitif jadi ngerekamnya gak dari awal gerakan. Fungsi timelapse nya juga agak jelek, gak bisa yg lumayan bagus gitu hasilnya.

Selain itu efeknya adalah suhu raspberry pi jadi naik diatas 80 derajat celcius, kadang2 kalo udah kepanasan gitu kameranya jadi agak ngaco, harus saya restart service kamera plus apache juga harus direstart. Yg bikin suhu tinggi sebenernya bukan kameranya, tapi karena raspberrynya juga dipake untuk nonton video lewat browser.

Saya coba2 ganti2 konfigurasi, hasilnya malah gak bisa jalanin aksi apapun dari web interfacenya, timelapse dan motion detection gak bisa jalan. Saya coba mau langsung akses ke kamera pake ffmpeg selalu gak bisa akses ke /dev/video0, begitu saya baca2 dan liat2 di raspberrynya ternyata itu device udah dipake sama service yg namanya raspimjpeg.

Terus di paket program RPi-Cam-Web-Interface ada file php yg namanya “cam_pic.php” yang kalo dibuka di browser isinya file jpg kamera terakhir (kalo di refresh gambarnya berubah), begitu saya liat, isinya ternyata sederhana sekali, intinya cuma 1 baris perintah: readfile("/dev/shm/mjpeg/cam.jpg").

Jadi saya kira service raspimjpeg itu menyiapkan still image di /dev/shm/mjpeg/cam.jpg yang diupdate pada rentang waktu tertentu. Nah, berbekal asumsi itu saya bikin aja bash script untuk copy file itu dengan jeda 0.3 detik (10 frame dalam 3 detik) dan disimpen dengan nama baru + sequence (nomor urut framenya). Sesudah itu (saya set tiap 1000 frame) baru eksekusi ffmpeg untuk bikin video timelapse dengan fps=15, jadi hasilnya kaya film Charlie Chaplin yg orangnya bergerak cepet banget.

Biar timelapsenya nyambung terus saya pisahkan script untuk bikin video mp4nya. Sesudah itu, biar storagenya gak cepet abis, saya upload deh mp4nya ke Mega.co.nz. Kenapa Mega? Karena si Mega.co.nz ini punya program untuk upload file ke storagenya dan programnya bisa dijalankan lewat scripting. Kurang lebih begini alurnya:

Script Copy JPG

  • LOOP START
  • Ambil tanggal dan jam saat ini
  • Bikin folder berdasarkan tgl dan jam
  • Copy file jpg dari /dev/shm/mjpeg/cam.jpg ke folder di atas sekalian ganti namanya dengan sequence.
  • Lakukan copy file 1000x dengan jeda 0.3 detik per copy file
  • Jalankan script untuk bikin mp4
  • Script ini tidak menunggu proses buat mp4 selesai, langsung kembali ke awal (LOOP START)

Script Bikin MP4

  • Jalankan ffmpeg untuk membuat video mp4
  • Hapus folder yang berisi frame
  • Jalankan script untuk mengupload video hasilnya

Script Upload

  • Upload 1 file ke sebuah folder di cloud

Udah gitu doang. Tapi hasilnya lumayan.

Update (4 April 2020):

Sebenernya scriptnya udah lama diganti, tapi males update blog. Jadi baru sekarang updatenya. Saya penasaran apa itu /dev/shm yang ternyata begitu di-google langsung ketahuan: ram disk. Jadi itu bagian dari RAM yang bisa diakses seperti storage. Akhirnya saya juga pake itu /dev/shm untuk nyimpen frame dan video yang dibuat, karena sesudah dibuat video data framenya dihapus dan sesudah diunggah data videonya dihapus jadi bisa rolling gak penuh2.

Kebayang kan kalo pake sdcard yang dibatesin frekuensi tulisnya nulis ratusan ribu file per hari, bisa cepet kadaluarsa itu sdcard.

Btw, scriptnya gak saya ganti, silakan ganti sendiri, gampang kok, tinggal tambahin path /dev/shm/apa-gitu didepan semua path untuk nyimpen file dan videonya.

#!/bin/bash
LOGF=/home/pi/.timelapse.log
END=1000
while true; do
    FIL="TL.$(date +%Y.%m.%d-%H.%M.%S)"
    echo "$(date +%Y.%m.%d-%H.%M.%S) Capturing $FIL" >> $LOGF 2>&1
    mkdir $FIL
    cd $FIL
    for i in $(seq -w 1 $END); do
        cp /dev/shm/mjpeg/cam.jpg "./${FIL}.${i}.jpg" 2>/dev/null
        if [ $? -ne 0 ]; then
            echo "$(date +%Y.%m.%d-%H.%M.%S) Retrying copy cam.jpg #${i}" >> $LOGF 2>&1
            cp /dev/shm/mjpeg/cam.jpg "./${FIL}.${i}.jpg"
        fi
        sleep .3
    done
    cd ..
    ./lt.sh $FIL &
done
cd ..

#!/bin/bash
LOGF=/home/pi/.timelapse.log
echo "$(date +%Y.%m.%d-%H.%M.%S) Merging $1" >> $LOGF 2>&1
ffmpeg -hide_banner -loglevel panic -nostats -r 15 -i $1/$1.%04d.jpg -c:v libx264 -vf fps=25 -pix_fmt yuv420p CAM-$1.mp4
rm -rf $1
echo "$(date +%Y.%m.%d-%H.%M.%S) Done Merging $1" >> $LOGF 2>&1
./mega.sh $1
#!/bin/bash
LOGF=/home/pi/.timelapse.log
echo "$(date +%Y.%m.%d-%H.%M.%S) Uploading $1" >> $LOGF 2>&1
mega-put CAM-$1.mp4 /motion/ >/dev/null 2>&1
rm CAM-$1.mp4
echo "$(date +%Y.%m.%d-%H.%M.%S) Success Uploading $1" >> $LOGF 2>&1

Note: script di atas kalo ada tulisan &amp itu sebenernya cuma karaketer “&”, keubah otomatis jadi kode htmlnya.

Sesudah bikin blog, langkah selanjutnya adalah mendaftarkan blog ini untuk di index di search engine. Maka saya langsung meluncur ke dmoz.org. Tapi ternyata dmoz.org udah ditutup, yg ada tinggal mirrornya aja dan saya gak dapetin cara untuk nambahin blog saya dalam salah satu direktorinya.

Akhirnya saya nyari direktori internet lain yg bisa nampung blog saya ini. Akhirnya saya dapet daftar dari “Free Web Directories” yg ternyata gak free2 amat. Saya penasaran memangnya apa sih yg bikin web direktori itu gak free, datanya sebesar apa yg dibutuhkan untuk data web direktori itu?

Saya berburu data. Dengan bersenjatakan google, akhirnya saya dapet mangsa juga: Dataverse. Dapet data dmoz.org per 12 Juni 2016. Ada 3 file yg bisa didownload, dan yang saya proses duluan yg tab delimited csv.

Sekilas lihat datanya, saya langsung bikin table di MySQL, 3 table, standar aja (id primary key autonumber) 1 table struktur folder, 1 table daftar domain, 1 table mapping domain dan folder. Table “directory” isinya ID, NamaFolder, Parent_ID. Table “domain” isinya ID, NamaDomain. Table “domain_map” isinya ID, Domain_ID, Folder_ID.

Tab delimited file cuma ada 2 field, domain dan array of path yg nantinya akan dimapping ke table “directory”. Program dibuat menggunakan PHP (bukan yg dibuka pake browser, tapi yg di jalanin lewat command prompt). Awalnya program berjalan lancar, tanpa hambatan, cepat. Tapi lama2 makin kelihatan lambat. Karena dlm scriptnya saya selalu memeriksa keberadaan data sebelum di insert, maka akhirnya saya buat index yang sesuai untuk semua table.

Program kelihatan lebih cepat jalannya, tapi itu gak bertahan lama, gejala melambat langsung terlihat. Akhirnya program saya ubah lagi, terutama dibagian akses database. Yg sebelumnya pake fungsi, akhirnya saya buat PDO prepared statement untuk tiap query, jadi pas looping data cukup memanggil method execute dengan parameter yang sesuai. Ada kemajuan kecepatan walaupun tidak signifikan.

Saya sadar sebenarnya index mempercepat perintah select, tapi memperlambat perintah insert. Dan semakin datanya banyak tambah beban juga. Akhirnya saya memutuskan untuk memakai cache data berupa array. Data table saya load ke dalam array, jadi pengecekan data existing dan lookup id saya lakukan pada array tidak mengakses database sama sekali, akses database hanya dilakukan pada saat insert data. Ini membuat database tidak memerlukan index (selain primary key).

Saat scriptnya dijalankan, error: out of memory. Saya lupa ngeset maksimum memorynya. Running kedua kali… Wussss… langsung terlihat perbedaannya. Memang startupnya lama karena memuat semua data ke array, tapi sesudah itu data dengan amat sangat lancar dibaca dan distore ke database.

Jadi seperti yang pernah saya tulis di entry blog sebelumnya: Selalu cari jalan tercepat, jangan puas hanya dengan hasil yang benar.

Update:

Diujung (row ke 2.3jt dari 2.4jt), memory yang dibutuhin udah ngelewatin batesan yg saya tentuin (1.6GB). Karena keterbatasan sisa RAM yg saya punya (2GB), akhirnya saya pake metode hybrid, yg di load ke array adalah data yang paling banyak di select, yaitu data directory, sisanya tetap akses ke database (dengan index). Hasilnya walaupun gak secepet yg full array, masih lebih cepat dari pada full db.

MySql Table Information

 

Console View and Source Text

Speed is everything, but I can’t bite off more than I can chew.

Waktu jalan2 di deepweb lewat TOR, saya banyak ketemu sama no-script website, isinya biasanya cuma link ke file2 teks yang memang benar2 tanpa script. Akhirnya dapet deh inspirasi untuk bikin website tanpa client-side-script, awalnya semangat, tapi begitu dipikir-pikir, program (web-based) apa yg bisa bekerja dengan baik tanpa JavaScript? Susah juga nih.

Sesudah mengingat dan menimbang, akhirnya saya memutuskan untuk bikin program Password Keeper (PaKe) tanpa client-side-script. Selain bisa dipercaya di dunia bawang (onion world) karena tanpa script, program ini juga cukup berguna untuk pemakai komputer se-hari2.

Untuk sementara ini, source-code nya blm bisa dipublikasi karena memang programnya belum selesai. Btw, karena “No screenshot”=Hoax, maka ini dia screenshotnya:

Style nya mau kaya console, tapi karena bikin simulasi console di web hampir mustahil tanpa JavaScript, akhirnya cuma tampilannya aja yg kaya console, tapi pengoperasian progamnya tetep pake klik link. Tapi “cursor” yg kedip2 di paling bawah itu tanpa script juga loh, murni pake CSS.

Pengoperasian programnya mirip make file manager, bisa bikin folder, bisa bikin item. Folder bisa punya sub-folder dan bisa punya item. Item punya nama dan isinya free-text yang disimpan dalam keadaan terenkripsi. Database disimpan dalam format SQLite, program dibuat dengan PHP.

Fasilitas yg belum ada:

  • Hapus Item
  • Hapus Folder
  • Copy Item/Folder ke “clipboard” (dlm progam saya sebut dengan ‘Pundi’)
  • Paste Item/Folder dalam “clipboard” ke active folder
  • Clear isi “clipboard”

Kalo udah selesai semua saya publish deh source-code nya.

Udah ah, segitu aja.