Как добавить и выполнить двоичный файл в функциях Azure?

#python #linux #azure #azure-functions

#python #linux #azure #azure-функции

Вопрос:

Мне нужно запустить двоичный файл Linux ( ffmpeg ради этого примера) из функции Azure, которая запускает python / linux.

Я не нашел, как его упаковать и как его выполнить.

Некоторые документы по python в Azure показывают, что в пакете функции может быть bin/ корневая папка. Поместить файл туда и затем вызвать subprocess.run() его не удается. По-видимому, он не может найти исполняемый файл.

Я пытался переместить файл в корневой каталог или попытаться найти его по полному пути (я пробовал /home/site/www и его варианты). По-прежнему безуспешно.

Чего мне не хватает?

Ответ №1:

Я следовал официальному руководству Create your first Python function in Azure (preview) по созданию HttpTrigger функции для Python и пробовал разные способы заставить ffmpeg работать функции Azure, тогда у меня это работает.

Вот мои шаги, чтобы сделать это выше, как показано ниже, надеюсь, это поможет.

  1. Следуйте официальному руководству по Azure Funtions for Python для установки Azure Functions Core Tools на моем локальном компьютере с Windows, чтобы создать проект с именем MyFunctionProj и функцию с именем HttpTrigger .

  2. Перед загрузкой ffmpeg с deployment я проверяю архитектуру платформы операционной системы моего экземпляра Azure Functions в Azure, изменяя официальный пример кода на приведенный ниже код.

     # add these codes
    import platform, os
    .....
    
    def main(req: func.HttpRequest) -> func.HttpResponse:
        if name:
            return func.HttpResponse(f"Hello {name}! {platform.architecture()}")
      

    Его результат Hello peter-pan! ('64bit', '') в broswer.

  3. Затем я помещаю ffmpeg статический двоичный файл AMD64, загруженный с https://johnvansickle.com/ffmpeg / в мой MyFunctionProj и измените мой код ниже, чтобы проверить путь к файлу и дать команду func azure functionapp publish <my app name> опубликовать в Azure.

     def main(req: func.HttpRequest) -> func.HttpResponse:
        if name:
            return func.HttpResponse(f"Hello {name}! {platform.architecture()} {os.listdir()} {os.listdir('HttpTrigger')}")
      

    Его результат Hello peter-pan! ('64bit', '') ['in.mp4', 'ffmpeg', 'host.json', 'requirements.txt', 'ffmpeg.exe', '.python_packages', 'HttpTrigger'] ['in.mp4', '__pycache__', 'sample.dat', 'host.json', 'function.json', '__init__.py'] в broswer такой же, как в моем MyFunctionProj

  4. Я обнаружил, что все, что находится в MyFunctionProj папке, будет загружено в Azure, и вызываю os.listdir() , чтобы показать список файлов MyFunctionProj , поэтому текущий путь в Python такой же, как MyFunctionProje локально. Затем я попытался вызвать ffmpeg в своей локальной среде Windows с помощью приведенного ниже кода.

     def main(req: func.HttpRequest) -> func.HttpResponse:
        if name:
            return func.HttpResponse(f"Hello {name}! {platform.architecture()} {os.listdir()} {os.listdir('HttpTrigger')} {os.path.exists('in.mp4')} {os.popen('ffmpeg.exe -i in.mp4 out.mp4').read()} {os.path.exists('out.mp4')} {os.popen('del out.mp4').read()}")
      

    Он работает для вывода файла out.mp4 с помощью команды ffmpeg.exe -i in.mp4 out.mp4 , а затем рассматривает возможность воспроизведения его в command del out.mp4 .

  5. Попробуйте заставить его работать в среде Linux в функции Azure, я меняю команды на ./ffmpeg -i in.mp4 out.mp4 и rm out.mp4 . Но это не сработало в функции Azure. Это может быть вызвано отсутствием разрешения на выполнение ffmpeg двоичного файла Linux при загрузке из Windows. Итак, я проверил свое предположение с помощью command ls -l ffmpeg и chmod u x ffmpeg , прежде чем вызвать его.

     def main(req: func.HttpRequest) -> func.HttpResponse:
        if name:
            return func.HttpResponse(f"Hello {name}! {platform.architecture()} {os.listdir()}  {os.listdir('HttpTrigger')} {os.popen('ls -l ffmpeg').read()} {os.popen('chmod u x ffmpeg').read()} {os.popen('ls -l ffmpeg').read()} {os.path.exists('in.mp4')} {os.popen('./ffmpeg -i in.mp4 out.mp4').read()} {os.path.exists('out.mp4')} {os.popen('rm out.mp4').read()}")
      

    Теперь это работает, результат такой, как показано ниже, я красиво оформил его.

     Hello peter-pan! // Offical sample output
    ('64bit', '') // the Linux platform architecture of Azure Functions for Python 
    ['in.mp4', 'ffmpeg', 'host.json', 'requirements.txt', 'ffmpeg.exe', '.python_packages', 'HttpTrigger']  // file list of MyFunctionProj
    ['in.mp4', '__pycache__', 'sample.dat', 'host.json', 'function.json', '__init__.py'] // file list of HttpTrigger
    -r--r--r-- 1 root root 69563752 Mar 13  2019 ffmpeg // before chmod u x
    -rwxr--r-- 1 root root 69563752 Mar 13  2019 ffmpeg // after chmod u x
    True  // in.mp4 exists
    True // out.mp4 exists before delete it using `rm`
      

Примечание: Я думаю, что проблема с разрешением на выполнение ffmpeg возникнет, когда вы разрабатывали в Linux. И in.mp4 файл поступает из https://github.com/kkroening/ffmpeg-python/blob/master/examples/in.mp4. Я пытался использовать ffmpeg-python package для реализации ваших потребностей, но, похоже, он не работает на local и Azure.

Ответ №2:

Вы можете запускать такие команды, как apt-get install ffmpeg из консоли Kudu на https://<YOUR-APP>.scm.azurewebsites.net .

Но среда будет сброшена, если вы развернете или масштабируете свое приложение. Другим решением было бы использовать развертывание docker, чтобы вы могли указать, какие двоичные файлы вы хотите добавить на сервер.