{"id":1090,"date":"2021-07-06T15:50:12","date_gmt":"2021-07-06T13:50:12","guid":{"rendered":"https:\/\/vitocafazzo.it\/site_Wp\/?p=1090"},"modified":"2021-07-10T13:09:23","modified_gmt":"2021-07-10T11:09:23","slug":"rb-pratica-swap-video","status":"publish","type":"post","link":"https:\/\/vitocafazzo.it\/site_Wp\/2021\/07\/06\/rb-pratica-swap-video\/","title":{"rendered":"RB Pratica &#8211; Swap video"},"content":{"rendered":"\n<p class=\"has-text-align-center wp-block-paragraph\"><a href=\"https:\/\/vitocafazzo.it\/site_Wp\/appunti-raspberry\/\" data-type=\"URL\" data-id=\"https:\/\/vitocafazzo.it\/site_Wp\/appunti-raspberry\/\">Torna all&#8217;elenco<strong> Raspberry<\/strong><\/a><\/p>\n\n\n\n<div id=\"block-5361e2c4-5bc4-498c-8304-9c85759acc67\" class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/vitocafazzo.it\/site_Wp\/wp-content\/uploads\/2021\/07\/TT_Raspberry.jpg\" alt=\"Questa immagine ha l'attributo alt vuoto; il nome del file \u00e8 TT_Raspberry.jpg\"\/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"block-bd52a6e6-cc2c-4946-b7e1-5a5d36d85c86\">Specifiche<\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>All&#8217;avvio RB parte con la presentazione di un video (<em>VIDEO_01<\/em>). Il <em>VIDEO_01<\/em> viene ripetuto in loop.<\/li><li>Al verificarsi di un evento (in questo caso la pressione di un pulsante) si interrompe il primo video e ne parte un secondo (<em>VIDEO_02<\/em>).<\/li><li>Una volta terminata la visione del <em>VIDEO_02<\/em>, riprende il <em>VIDEO_01<\/em> dal punto in cui e&#8217; stato interrotto<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"block-bd52a6e6-cc2c-4946-b7e1-5a5d36d85c86\">Materiale<\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>Raspberry PI 3<\/li><li>Scheda da 16GB<\/li><li>Pulsante<\/li><li>Resistenza 10K<\/li><li>Cavetti per collegamenti<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"block-bd52a6e6-cc2c-4946-b7e1-5a5d36d85c86\">Sistema operativo: Raspberry PI OS FULL (Ex Raspbian)<\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>Parte &#8216;immediatamente&#8217;<\/li><li>Per partire non ha bisogno dell&#8217;inserimento di nome-utente e password (di default <strong>pi<\/strong> e <strong>raspberry<\/strong>). La password la reimposto in <strong>rb<\/strong><\/li><li>Settaggio veloce: lingua, password, network e aggiornamento sistema (che prende un po&#8217; piu&#8217; di tempo)<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Nota 1<\/strong>: In futuro testare il <em>lavoro<\/em> su Raspberry PI OS LITE<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Nota 2<\/strong>: Ho cercato di lavorare con &#8216;Ubuntu-MATE&#8217; per RB: lento, problemi con VNC e non ha abilitato alcuni repository necessari. ABBANDONATO<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<h3 class=\"wp-block-heading\" id=\"block-bd52a6e6-cc2c-4946-b7e1-5a5d36d85c86\">Collegamenti con il Raspberry<\/h3>\n\n\n\n<h6><strong><u>Vnc-Server<\/u><\/strong><\/h6>\n\n\n\n<p class=\"wp-block-paragraph\">Su <em>Raspberry PI OS FULL<\/em> <strong>VNC<\/strong> e&#8217; preinstallato. Per attivarlo richiamare il tool di configurazione raspi-config: <code>sudo raspi-config<\/code>. Selezionare <em>Interfacing Options<\/em> dal menu, poi l&#8217;opzione <em>VNC<\/em> e infine attivarla con <em>Yes<\/em>.<\/p>\n<\/div><\/div>\n\n\n\n<h6><strong><u>Server Ssh<\/u><\/strong><\/h6>\n\n\n\n<p class=\"wp-block-paragraph\">Non necessario, ma potrebbe essere utile. Dovrebbe essere preinstallato, in caso contrario: <code>sudo apt-get install openssh-server<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Senza questo comando <code>sudo \/etc\/init.d\/ssh restart<\/code> da dare a RB, <strong>SSH<\/strong> non funziona. Per evitare di <em>darlo<\/em> ogni volta \u00e8 stato inserito in <em>\/etc\/rc.local<\/em> prima dell&#8217;istruzione <code>exit 0<\/code><\/p>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<h3 class=\"wp-block-heading\" id=\"block-bd52a6e6-cc2c-4946-b7e1-5a5d36d85c86\">Crontab<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Nei sistemi operativi Linux, il comando&nbsp;<strong>crontab<\/strong>&nbsp;consente di pianificare l&#8217;esecuzione automatica periodica di attivit\u00e0 o script. Ogni attivit\u00e0 schedulata \u00e8 chiamata&nbsp;<strong>cron job<\/strong>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/guide.debianizzati.org\/index.php\/Utilizzo_del_servizio_di_scheduling_Cron\" data-type=\"URL\" data-id=\"https:\/\/guide.debianizzati.org\/index.php\/Utilizzo_del_servizio_di_scheduling_Cron\" target=\"_blank\" rel=\"noreferrer noopener\">Guida Crontab<\/a><\/p>\n\n\n\n<h6><strong><u>Istruzioni<\/u><\/strong><\/h6>\n\n\n\n<ul class=\"wp-block-list\"><li><code>crontab -e<\/code>: permette di aggiungere\/modificare\/eliminare le attivita&#8217; schedulate<\/li><li><code>crontab -l<\/code>: permette di verificare le attivita&#8217; schedulate, senza poterle modificare<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">In verit\u00e0, il comando che mi ha permesso di proseguire senza intoppi (dove viene anche specificato l&#8217;utente) \u00e8 il seguente: <code>sudo crontab -u pi -e<\/code><\/p>\n<\/div><\/div>\n\n\n\n<h6><strong><u>Eventi<\/u><\/strong><\/h6>\n\n\n\n<p class=\"wp-block-paragraph\">Oltre a gestire eventi &#8220;temporali&#8221;, <em>il cron job<\/em> pu\u00f2 attivare script al riavvio del server linux con l&#8217;istruzione<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>@reboot \/PATH\/NOME_SCRIPT.sh<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lo script realizzato che deve essere lanciato all&#8217;avvio \u00e8 uno script scritto in PYTHON che, in alcuni casi, non partiva. La soluzione \u00e8 stata quella di inserire il <em>cron job<\/em> con la seguente istruzione:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>@reboot sleep 20 &amp;&amp; python3 \/home\/pi\/Desktop\/SwapVideo\/SwapVideo.py &gt;&gt; \/dev\/null 2&gt;&amp;1<\/code><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Sleep di 20 secondi per permettere al sistema di caricarsi.<\/li><li>Nel file di <em>log<\/em>, in alcuni casi, ho trovato il seguente messaggio di errore: &#8220;<em>info (No MTA installed, discarding output\u2026<\/em>&#8220;. Questo accade perch\u00e8 i lavori <em>cron<\/em>, a volte, producono output e il <em>demone<\/em> tenta di inviarlo via email. Se non si ha bisogno di quell&#8217;output, il modo pi\u00f9 semplice per risolvere il problema \u00e8 scartarlo direttamente dal <em>crontab<\/em> inviando il tutto ad un device NULLO :<code> &gt;&gt; \/dev\/null 2&gt;&amp;1<\/code>.<\/li><li>Il file di log \u00e8 il seguente: <em>\/var\/log\/cron.log<\/em><\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"block-bd52a6e6-cc2c-4946-b7e1-5a5d36d85c86\">Visualizzazione del video<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Per la visualizzazioe dei video, in un primo momento, ho utilizzato <em>omxplayer<\/em> (preinstallato su RB) richiamato da python con <em>subprocess<\/em>, ma la cosa non mi ha convinto molto.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.raspberrypi.org\/documentation\/raspbian\/applications\/omxplayer.md\" data-type=\"URL\" data-id=\"https:\/\/www.raspberrypi.org\/documentation\/raspbian\/applications\/omxplayer.md\" target=\"_blank\" rel=\"noreferrer noopener\">Guida omxplayer<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Una soluzione pi\u00f9 elegante, a mio parere, \u00e8 possibile utilizzando il modulo <em>omxplayer-wrapper<\/em> all&#8217;interno di python. Per la sua installazione: <code>pip3 install omxplayer-wrapper<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a rel=\"noreferrer noopener\" href=\"https:\/\/guide.debianizzati.org\/index.php\/Utilizzo_del_servizio_di_scheduling_Cron\" data-type=\"URL\" data-id=\"https:\/\/guide.debianizzati.org\/index.php\/Utilizzo_del_servizio_di_scheduling_Cron\" target=\"_blank\">Guida omxplayer-<\/a><a rel=\"noreferrer noopener\" href=\"https:\/\/python-omxplayer-wrapper.readthedocs.io\/en\/latest\/omxplayer\/\" data-type=\"URL\" data-id=\"https:\/\/python-omxplayer-wrapper.readthedocs.io\/en\/latest\/omxplayer\/\" target=\"_blank\">wrapper<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"block-bd52a6e6-cc2c-4946-b7e1-5a5d36d85c86\">Circuito<\/h3>\n\n\n\n<a target=\"_blank\" href=\"https:\/\/vitocafazzo.it\/site_Wp\/wp-content\/uploads\/2021\/07\/Raspberry_SwapVideo_Circuito.jpg\" rel=\"noopener\">\n   <img decoding=\"async\" src=\"https:\/\/vitocafazzo.it\/site_Wp\/wp-content\/uploads\/2021\/07\/Raspberry_SwapVideo_Circuito.jpg\" alt=\"Circuito\" width=\"120\"> \n<\/a>\n\n\n<a target=\"_blank\" href=\"https:\/\/vitocafazzo.it\/site_Wp\/wp-content\/uploads\/2021\/07\/Raspberry_SwapVideo_GPIO.jpg\" rel=\"noopener\">\n   <img decoding=\"async\" src=\"https:\/\/vitocafazzo.it\/site_Wp\/wp-content\/uploads\/2021\/07\/Raspberry_SwapVideo_GPIO.jpg\" alt=\"Raspberry_GPIO\" width=\"120\"> \n<\/a>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"block-bd52a6e6-cc2c-4946-b7e1-5a5d36d85c86\">File<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">La cartella <em>SwapVideo<\/em>, creata sul <em>Desktop<\/em>, deve contenere i seguenti file:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>SwapVideo.py<\/li><li>Video_01.mp4<\/li><li>Video_02.mp4<\/li><\/ul>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" title=\"Script SwapVideo.py\">#!\/usr\/bin\/env python3\n\nimport RPi.GPIO as GPIO\nfrom omxplayer.player import OMXPlayer\nfrom time import sleep\n\n\nimport subprocess\n# ============================================\n# Restitutisce la durata di un video in sec.\n# --------------------------------------------\ndef get_durata(filename):\n    result = subprocess.run([\"ffprobe\", \"-v\", \"error\", \"-show_entries\",\n                             \"format=duration\", \"-of\",\n                             \"default=noprint_wrappers=1:nokey=1\", filename],\n        stdout=subprocess.PIPE,\n        stderr=subprocess.STDOUT)\n    return int(float(result.stdout))\n# ==============================================\n\n\n# Definizioni varabili video (percorso completo)\n# -----------------------------------------------\nVideo_01 = \"\/home\/pi\/Desktop\/SwapVideo\/Video_01.mp4\"\nVideo_02 = \"\/home\/pi\/Desktop\/SwapVideo\/Video_02.mp4\"\ndurata_video_02=get_durata(Video_02)\n\n\n# settaggio PIN per l'INPUT\n# --------------------------------------------\nmy_pin=21\n\nGPIO.setmode(GPIO.BCM)\nGPIO.setup(my_pin,GPIO.IN)\n\n\n# LOOP primo video\n# --------------------------------------------\nplayer_01 = OMXPlayer(Video_01, args=['--loop'], dbus_name=\"omxplayer.player_01\")\n\n\n\nval=0 # associato al valore del pin\nwhile True:\n\tval=GPIO.input(my_pin)\n\tif val==1:\n\t\t# attende rilascio\n\t\twhile val==1:\n\t\t\tval=GPIO.input(my_pin)\n\t\t\tsleep(.5)\n\t\t\n\t\t# PAUSA e NASCONDE video1\n\t\tplayer_01.pause()\n\t\tplayer_01.hide_video()\n\t\t\n\t\t# VISUALIZZA video2\n\t\tplayer_02 = OMXPlayer(Video_02, dbus_name=\"omxplayer.player_02\")\n\t\tplayer_02.show_video()\n\t\tplayer_02.play()\n\t\t\t\n\t\t# Attende visualizzazione completa video2 e lo chiude \t\n\t\tsleep(durata_video_02)\n\t\tplayer_02.quit()\n\t\t\n\t\t# Riprende visualizzazione video1\n\t\tplayer_01.show_video()\n\t\tplayer_01.play()<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Conclusione<\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>Preparare MicroSD con <em>Raspberry PI OS FULL<\/em><\/li><li>Settare lingua, password e network<\/li><li>Aggiornare il sistema<\/li><li>Attivare <em>VNC Server<\/em> (raspi-config)<\/li><li>Per utilizzare SSH (opzionale) inserire all&#8217;interno del file<em> \/etc\/rc.local <\/em>l&#8217;istruzione<code>  \/etc\/init.d\/ssh restart<\/code> prima di <code>exit 0<\/code><\/li><li>Copiare nella cartella <em>\/home\/pi\/Desktop\/SwapVideo<\/em> i file: <em>SwapVideo.py<\/em>, <em>Video_01.mp4<\/em> e <em>Video02.mp4<\/em> (da VNC Viewer, SSH o collegando la MicroSD al pc)<\/li><li>Inserire il <em>cron job<\/em> <code> @reboot sleep 20 &amp;&amp; python3 \/home\/pi\/Desktop\/SwapVideo\/SwapVideo.py &gt;&gt; \/dev\/null 2&gt;&amp;1 <\/code> dopo aver digitato <em>sudo crontab -u pi -e<\/em><\/li><li>Realizzare il circuito.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Per i test ho realizzato un secondo script (<em>SwapVideo_KEY.py<\/em>) dove viene gestito l&#8217;evento da tastiera e non con un pulsante.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" title=\"Script SwapVideo_KEY.py\">#!\/usr\/bin\/env python3\n\nfrom omxplayer.player import OMXPlayer\nfrom time import sleep\n\n\nimport subprocess\n# ============================================\n# Restitutisce la durata di un video in sec.\n# --------------------------------------------\ndef get_durata(filename):\n    result = subprocess.run([\"ffprobe\", \"-v\", \"error\", \"-show_entries\",\n                             \"format=duration\", \"-of\",\n                             \"default=noprint_wrappers=1:nokey=1\", filename],\n        stdout=subprocess.PIPE,\n        stderr=subprocess.STDOUT)\n    return int(float(result.stdout))\n# ==============================================\n\n\n# Definizioni varabili video (percorso completo)\n# -----------------------------------------------\nVideo_01 = \"\/home\/pi\/Desktop\/SwapVideo\/Video_01.mp4\"\nVideo_02 = \"\/home\/pi\/Desktop\/SwapVideo\/Video_02.mp4\"\ndurata_video_02=get_durata(Video_02)\n\n\n# LOOP primo video\n# --------------------------------------------\nplayer_01 = OMXPlayer(Video_01, args=['--loop'], dbus_name=\"omxplayer.player_01\")\n\n# =============================================================\n#\tMENU DI CONTROLLO\n# =============================================================\nselezione = 0\nwhile True:\n\tprint (\"\\n\")\n\tprint (\"-----------------------------------\")\n\tprint (\" OPERAZIONI\")\n\tprint (\"-----------------------------------\")\n\tprint (\" s. Swap Video\")\n\tprint (\" x. Esci\")\n\tprint (\"-----------------------------------\")\n\tselezione = input(\"Opzione: \")\n\t\n\t#***********************************\n\tif selezione in [\"s\",\"S\"]:\t\t\n\t\t# PAUSA e NASCONDE video1\n\t\tplayer_01.pause()\n\t\tplayer_01.hide_video()\n\t\t\n\t\tprint (\" &gt;&gt;&gt; IN ATTESA DELLA FINE DEL VIDEO\")\n\t\n\t\t# VISUALIZZA video2\n\t\tplayer_02 = OMXPlayer(Video_02, dbus_name=\"omxplayer.player_02\")\n\t\tplayer_02.show_video()\n\t\tplayer_02.play()\n\t\t\t\n\t\t# Attende visualizzazione completa video2 e lo chiude \t\n\t\tsleep(durata_video_02)\n\t\tplayer_02.quit()\n\t\t\n\t\t# Riprende visualizzazione video1\n\t\tplayer_01.show_video()\n\t\tplayer_01.play()\n\t\t\n\t#***********************************\n\telif selezione in [\"x\",\"X\"]:\n\t\tprint (\"&gt;&gt;&gt; CIAO!!!!\")\n\t\tplayer_01.quit()\n\t\tbreak\n\t#***********************************\n\telse:\n\t\tprint (\" &gt;&gt;&gt; OPZIONE NON VALIDA\")\n\t#***********************************<\/pre><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Torna all&#8217;elenco Raspberry Specifiche All&#8217;avvio RB parte con la presentazione di un video (VIDEO_01). Il VIDEO_01 viene ripetuto in loop. Al verificarsi di un evento (in questo caso la pressione di un pulsante) si interrompe il primo video e ne parte un secondo (VIDEO_02). Una volta terminata la visione del VIDEO_02, riprende il VIDEO_01 dal [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-1090","post","type-post","status-publish","format-standard","hentry","category-raspberry"],"_links":{"self":[{"href":"https:\/\/vitocafazzo.it\/site_Wp\/wp-json\/wp\/v2\/posts\/1090","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vitocafazzo.it\/site_Wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vitocafazzo.it\/site_Wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vitocafazzo.it\/site_Wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vitocafazzo.it\/site_Wp\/wp-json\/wp\/v2\/comments?post=1090"}],"version-history":[{"count":5,"href":"https:\/\/vitocafazzo.it\/site_Wp\/wp-json\/wp\/v2\/posts\/1090\/revisions"}],"predecessor-version":[{"id":1388,"href":"https:\/\/vitocafazzo.it\/site_Wp\/wp-json\/wp\/v2\/posts\/1090\/revisions\/1388"}],"wp:attachment":[{"href":"https:\/\/vitocafazzo.it\/site_Wp\/wp-json\/wp\/v2\/media?parent=1090"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vitocafazzo.it\/site_Wp\/wp-json\/wp\/v2\/categories?post=1090"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vitocafazzo.it\/site_Wp\/wp-json\/wp\/v2\/tags?post=1090"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}