1

I am using FFMPEG for my application. Works great when running the program through the terminal/VScode. However I wrote a .plist script to automate my python file and now I get an error saying, sh: ffmpeg: command not found. Tried adding the path to FFMPEG explicitly as one of the ProgramArguments but invain.

Anyone who has tried automating a script with .plist and facing this error?

My .plist file that I have placed it in ~/Library/LaunchAgents/

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>schedule.reel.launcher</string>
    <key>ProgramArguments</key>
    <array>
        <string>/opt/homebrew/Caskroom/miniconda/base/envs/venv_k2/bin/python</string>
        <string>/Users/***/Kokaato/musicheroku/automate_upload/schedule_reel_creation.py</string>
    </array>
    <key>StandardErrorPath</key>
    <string>/Users/***/Kokaato/musicheroku/automate_upload/python_script.error</string>
    <key>KeepAlive</key>
    <true/>
</dict>
</plist>

EDIT:

Updated code to help understand the problem better

import pandas as pd
import pafy
import os
import re
from utils import send_email


def create_reel():
    df = pd.read_csv("/Users/***/Kokaato/musicheroku/automate_upload/weekly_songs.csv", header=None)



    input_directory = "/Users/***/Kokaato/musicheroku/automate_upload/downloaded_songs"
    output_directory = "/Users/***/Kokaato/musicheroku/automate_upload/reel_videos"


    url = df.iloc[0,0]

    try:

        video = pafy.new(url)
    except Exception as e:
        send_email( _exception =  e, subject= "error in pafy.new line", filename="create_video_reels.py")

    best_video = video.getbest(preftype="mp4")

    title = "".join(re.findall("[a-zA-Z]+", str(video.title)))
    title = "".join(re.findall("[a-zA-Z]+", title))

    best_video.download(
        filepath=input_directory + "/{}.{}".format(title, best_video.extension)
    )

    try:
        os.system(
            "ffmpeg -i "
            + input_directory
            + "/"
            + title
            + "."
            + best_video.extension
            + " -ss 00:00:05 -to 00:00:19 -async 1 "
            + output_directory
            + "/video_reel.mp4"
        )


    except Exception as e:
        send_email( _exception =  e, subject= "Problem with ffmpeg", filename="create_video_reels.py")


    # delete link from csv
    df.drop(df.index[0], inplace=True)

    try:
        df.to_csv(path_or_buf="/Users/***/Kokaato/musicheroku/automate_upload/weekly_songs.csv", index=False, header=False)
    except Exception as e:
        send_email( _exception =  e, subject= "Problem creating reel", filename="create_video_reels.py")
DarkFantasy
  • 240
  • 3
  • 16
  • What's the value of `os.environ['PATH']` in the runtime environment for this process? And _where_ is this ffmpeg executable located? – Charles Duffy Jul 22 '21 at 20:11
  • ...the typical meaning of this is that your dotfiles set up some PATH entries in your personal interactive environment that aren't there for services out-of-the-box. – Charles Duffy Jul 22 '21 at 20:12
  • (BTW, `sh: ffmpeg: command not found` implies you're using `shell=True`, and you really shouldn't do that; _especially_ if filenames you got off the Internet are being substituted into code to build the commands to run -- unless it's done with great care the security implications are serious). – Charles Duffy Jul 22 '21 at 20:13
  • ...also, `sh: ffmpeg: command not found` won't happen if the code that's being run contains a fully-qualified path, so insofar as you're asserting that you _did_ change your code to fully-qualify the path, I'd double-check that the change you think you made was actually saved to the file being run by the plist; that there isn't an additional ffmpeg invocation in your code that you missed; etc. – Charles Duffy Jul 22 '21 at 20:16
  • Hey Charles. On a M1 mac, it is not straightforward to install FFMPEG. `os.environ['PATH']` value is -`'/opt/homebrew/Caskroom/miniconda/base/bin:/opt/homebrew/Caskroom/miniconda/base/condabin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin'` – DarkFantasy Jul 22 '21 at 20:36
  • I don't think I am using `shell=True` but my understanding of it might be flawed. Updated question for your reference. – DarkFantasy Jul 22 '21 at 20:40
  • That *"`os.environ['PATH']` value is..."* assertion -- is that what it is when you run Python on your user account, or is it what it is when you add logging to the script run by launchd from the plist? They won't be the same, and the latter is what I was asking for. – Charles Duffy Jul 22 '21 at 20:51
  • `os.system()` uses `sh`, and has the security vulnerabilities I mentioned re: danger of malicious filenames. Don't use it -- use `subprocess.run()` or `subprocess.Popen()` with `shell=False`, and a _list_ of arguments instead of a string. – Charles Duffy Jul 22 '21 at 20:52
  • See https://stackoverflow.com/a/25955884/14122, particularly the second part of the answer (showing a list). – Charles Duffy Jul 22 '21 at 20:55
  • ...though if you need to run ffmpeg from somewhere not in the PATH, replace `ffmpeg` with something like `/usr/local/bin/ffmpeg`, providing an _absolute_ path rather than a relative one. – Charles Duffy Jul 22 '21 at 20:55
  • Thanks, Charles. Really appreciate it. New to macOS. Give me a couple of days, I'll get back to you with proper answers to your queries. – DarkFantasy Jul 22 '21 at 20:57
  • Full path to the FFMPEG has worked. Is that the correct solution though? Or more of a hack? – DarkFantasy Jul 22 '21 at 21:28
  • if you don't have `ffmpeg` on `PATH` then it is solution. But if you plan to move code to other computer which may have `ffmpeg` in different place then it can be the problem. – furas Jul 22 '21 at 22:00
  • @DarkFantasy, ...the _correct solution_ is to have the plist specify a PATH that contains your ffmpeg executable's location. (Changing that plist, rather than the Python script, is the more appropriate way to customize for an individual computer, since on other operating systems -- with different ffmpeg locations -- you would be writing something like a systemd .service file or an Upstart definition to define the service, so there's a comparable place to specify the right PATH whenever you're building packaging for whatever your target OS may be). – Charles Duffy Jul 22 '21 at 22:19
  • Very clear and concise. Put it in an answer so that I can upvote and accept it. I know for a fact M1 mac users are struggling with such issues. Thanks, Charles! – DarkFantasy Jul 23 '21 at 09:31

0 Answers0