crontab und FFMPEG

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
Andykoa
User
Beiträge: 6
Registriert: Mittwoch 3. Juni 2020, 13:11

Hallo,
ich hoffe ich bin hier richtig.
Ich habe das Problem, dass ich ein py Skript zwar über die Konsole ausführen kann, jedoch nicht über crontab.
Das Problem liegt wohl an FFMPEG. Ich habe schon das Web durchsucht, viele Themen dazu gefunden, aber keines hatte die Lösung für mein Problem.
Ich hatte auch versucht das Skript über ein anderes Skript zu starten, was leider auch nicht geklappt hat. Da scheinen die richtigen Pfade nicht gefunden zu werden.

Ich bin da auch noch etwas neu und ehe Anfänger.
Ich hoffe hier kann mir geholfen werden.
Vielen Dank schon mal im voraus!

Das Skript nimmt alle Bilder eines Ordners und wandelt sie in ein Video um.

Code: Alles auswählen


import os
import time
import datetime
from picamera import PiCamera
from time import sleep
import ffmpeg


# BILDERPFAD
bilderpfad = "/home/pi/baustelle/bilder/"

# BILDER ORDNERNAME
ordnername = datetime.datetime.now().strftime("%y-%m-%d")
ordnernamedatum = bilderpfad + ordnername + "/"

# VIDEOPFAD
videopfad = "/home/pi/baustelle/videos/"

# VIDEO ORDNERNAME
videoordnernamedatum = videopfad + ordnername + "/"

# VIDEO DATUM ORDNER ERSTELLEN WENN NICHT VORHANDEN
if os.path.exists(videoordnernamedatum) == True:
    print (videoordnernamedatum, "existiert.") 
else:
    print (videoordnernamedatum, "existiert nicht.") 
    os.mkdir(videoordnernamedatum)
    print ("video ordner angelegt")

# VIDEO DATEI LOESCHEN WENN SCHON VORHANDEN

videodatei = videoordnernamedatum + "TAG-" + ordnername + ".mp4"
if os.path.isfile(videodatei):	# falls Dabei existiert
    os.remove(videodatei)
    print ("video datei war vorhanden und wurde geloescht")

# VIDEO ZUSAMMENBAUEN
(
 ffmpeg
    .input(ordnernamedatum + '*.jpg', pattern_type='glob', framerate=25)
    .output(videodatei)
	.overwrite_output()
    .run()
)

Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Kommentare komplett in großbuchstaben sind schwer zu lesen. Kommentare sollten beschreiben, warum etwas gemacht wird, das, was gemacht wird, steht ja schon im Code. Somit sind alle Kommentare überflüssig.
time, sleep und PiCamera werden importiert aber nicht benutzt.
Zwischen einer Funktion (print) und der öffnenden Klammer kommt kein Leerzeichen.
Konstanten schreibt man komplett gross: VIDEOPFAD. Pfade setzt man nicht mit + zusammen, sondern benutzt pathlib.Path. Explizit auf True zu prüfen ist überflüssig, weil das auch wiederum nur einen Wahrheitswert ergibt. Path.mkdir kennt eine exist_ok-Argument, so dass die if-Abfrage auch überflüssig wird.
`ordnername` ist wohl kein Ordername, wenn er auch Teil eines Dateinamens sein kann.

Code: Alles auswählen

import os
import datetime
import ffmpeg
from pathlib import Path

BILDERPFAD = Path("/home/pi/baustelle/bilder/")
VIDEOPFAD = Path("/home/pi/baustelle/videos/")

def main():
    timestamp = datetime.datetime.now().strftime("%y-%m-%d")
    videodatei = VIDEOPFAD / timestamp / f"TAG-{timestamp}.mp4"
    videodatei.parent.mkdir(parents=True, exists_ok=True)
    if videodatei.is_file():
        videodatei.unlink()
        print("video datei war vorhanden und wurde geloescht")
    ffmpeg.input(str(BILDERPFAD / timestamp / "*.jpg"), pattern_type='glob', framerate=25) \
        .output(str(videodatei)) \
        .overwrite_output() \
        .run()
)

if __name__ == '__main__':
    main()
Bei cron wird nicht die selbe Umgebung initialisiert wie in einer Shell. Wenn Du also noch irgendwelche Pfade gesetzt hast, damit ffmpeg läuft, kann es sein, dass die über cron nicht gefunden werden. Schau Dir mal die Error-Ausgabe an. Landet bei cron automatisch im internen `mail`-Ordner.
Andykoa
User
Beiträge: 6
Registriert: Mittwoch 3. Juni 2020, 13:11

Vielen Dank für die vielen Hinweise.
Wie gesagt bin ich noch Neuling und die Kommentare sind nur für mich wichtig.
Ich werde das gleich heute noch testen.
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Andykoa: Selbst für Dich als Neuling sind die Kommentare überflüssig. Was genau bringt Dir ``# BILDERPFAD`` vor einer Zeile ``bilderpfad = ...``? Das hat doch Null Informationswert. Und auch die anderen Kommentare haben nicht wirklichen Mehrwert. Man kann doch nahezu vorlesen was das Programm macht. Und da wo das nicht der Fall ist, sollte man sich überlegen den Code klarer zu schreiben. In der Regel liegt das dann an nicht gut gewählten Namen. Oder ist ein Zeichen, dass man eine Funktion einführen sollte, mit einem verständlichen Namen. Und da dann eventuell einen Docstring schreiben, statt Code zu kommentieren.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Andykoa
User
Beiträge: 6
Registriert: Mittwoch 3. Juni 2020, 13:11

@Sirius3

Beim ersetzen des Codes durch deinen erscheint der Fehler:

Code: Alles auswählen

File "videomachen.py", line 11
    videodatei = VIDEOPFAD / timestamp / f"TAG-{timestamp}.mp4"
                                                              ^
SyntaxError: invalid syntax
Der Pfeil steht unter den " nach der 4
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Dann ist wahrscheinlich das Python zu alt und kennt noch keine f-Zeichenkettenliterale. Dann muss man die `format()`-Methode auf Zeichenketten bemühen.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
import datetime
from pathlib import Path

import ffmpeg

BILDERPFAD = Path("/home/pi/baustelle/bilder/")
VIDEOPFAD = Path("/home/pi/baustelle/videos/")


def main():
    timestamp = datetime.datetime.now().strftime("%y-%m-%d")
    videodatei = VIDEOPFAD / timestamp / "TAG-{}.mp4".format(timestamp)
    videodatei.parent.mkdir(parents=True, exists_ok=True)
    if videodatei.is_file():
        videodatei.unlink()
        print("Videodatei war vorhanden und wurde geloescht.")
    ffmpeg.input(
        str(BILDERPFAD / timestamp / "*.jpg"),
        pattern_type="glob",
        framerate=25,
    ).output(str(videodatei)).overwrite_output().run()


if __name__ == "__main__":
    main()
Zuletzt geändert von __blackjack__ am Donnerstag 4. Juni 2020, 16:24, insgesamt 1-mal geändert.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Andykoa
User
Beiträge: 6
Registriert: Mittwoch 3. Juni 2020, 13:11

Wenn ich mein ursprüngliches Skript aus dem Crontab starte kommt folgende Fehlermeldung:

Code: Alles auswählen

From pi@raspberrypi  Thu Jun  4 17:20:05 2020
Return-Path: <pi@raspberrypi>
X-Original-To: pi
Delivered-To: pi@raspberrypi
Received: by raspberrypi (Postfix, from userid 1000)
	id 4444142CFB; Thu,  4 Jun 2020 17:20:05 +0200 (CEST)
From: root@raspberrypi (Cron Daemon)
To: pi@raspberrypi
Subject: Cron <pi@raspberrypi> python /home/pi/baustelle/videomachen.py
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/home/pi>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=pi>
Message-Id: <20200604152005.4444142CFB@raspberrypi>
Date: Thu,  4 Jun 2020 17:20:05 +0200 (CEST)

('/home/pi/baustelle/videos/20-06-04/', 'existiert.')
video datei war vorhanden und wurde geloescht
Traceback (most recent call last):
  File "/home/pi/baustelle/videomachen.py", line 41, in <module>
    .output(videodatei)
  File "/home/pi/.local/lib/python2.7/site-packages/ffmpeg/_run.py", line 320, in run
    overwrite_output=overwrite_output,
  File "/home/pi/.local/lib/python2.7/site-packages/ffmpeg/_run.py", line 285, in run_async
    args, stdin=stdin_stream, stdout=stdout_stream, stderr=stderr_stream
  File "/usr/lib/python2.7/subprocess.py", line 394, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1047, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory
Soweit ich das verstehe, werden bestimmte Dateien nicht gefunden, weil eine bestimmte Umgebungsvariable fehlt.
Vielleicht liege ich auch falsch.
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Andykoa: Zwei Probleme: Es wird mit Python 2 ausgeführt, und ``ffmpeg`` liegt anscheinend nicht in ``$PATH`` das aus ``/usr/bin`` und ``/bin`` besteht. Scheint kein per Paketverwaltung installiertes ``ffmpeg`` zu sein‽
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Andykoa
User
Beiträge: 6
Registriert: Mittwoch 3. Juni 2020, 13:11

@__blackjack__
Python 2 - Ja ich weiß - war mir nicht bewusst, dass ich zwingend Python 3.x brauche.
ffmepg habe ich mit PIP installiert.
Hast du da einen Codeschnipsel für mich bezgl. der $PATH Variable?
Und auf jeden Fall schon mal 1000 Dank für die spontane Hilfe hier im Forum.
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du hast ffmpeg garantiert nicht per pip installiert. Du hast vielleicht ein Python-Paket aenhlichen Namens mit pip installiert. Aber ffmpeg ist ein grosses Paket, dass du per Paketverwaltung deines Systems installieren musst. Dann ist das auch im Pfad. Mit Code hat das nix zu tun.
Andykoa
User
Beiträge: 6
Registriert: Mittwoch 3. Juni 2020, 13:11

@__deets__
Danke, das war wohl das Problem.
Scheint nun zu funktionieren.

Danke an euch alle!
Antworten