Автоматизация задач с Python #1: длительность видео

Мои курсы:
Boosty:
boosty.to/omolchanov/posts/99...
Patreon:
/ karty-vsekh-41011404
Скринкаст о том, как написать скрипт, вычисляющий длительность всех видео файлов в папке.
Содержание:
- рекурсивный поиск всех файлов в папке (os.walk())
- запуск сторонних программ (ffprobe/ffmpeg) из скрипта Python и получение их вывода (работа с модулем subprocess и классом Popen)
- немного о работе в терминале (перенаправление вывода, создание alias'ов для команд, как запускать Python-скрипты как команды)
Двигаюсь маленькими шажками.
Рассчитано на новичков.
Исходный код серии доступен в Patreon:
/ 30834965
Курс по парсингу сайтов (карта):
/ karta-kurs-na-30462246

Пікірлер: 103

  • @javanull262
    @javanull2624 жыл бұрын

    Очень полезный канал по питону. Лучший, который я видел. Объясняется довольно подробно и при этом лаконично, без воды, а не так чтобы хотелось отключить на половине видео от скуки или от ощущения, что видео создали в основном для того чтобы изнасиловать твои уши и глаза. Пользуюсь ютубом с детства, но комментарий оставляю в 1е. К сожалению, задонатить нету возможности. Попытаюсь поддержать хотябы так

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    Спасибо вам за отзыв

  • @aleksandrshevchenko5948
    @aleksandrshevchenko59484 жыл бұрын

    Олег, спасибо за ваш труд. Предлагаю немного переработанный вариант. Работает одинаково хорошо и на Windows, и на Linux. Для Windows имя файла берём в двойные кавычки, для Linux'а - экранируем ряд символов. В функции main указаны два способа выделения файла из пути, оба платформо-независимые. Всем удачи! [code] #!/usr/bin/env python3 import os import subprocess video_extensions = ['mp4', 'avi'] def get_videos() -> list: videos = [] for root, subfolders, files in os.walk(os.getcwd()): for file in files: if file.split('.')[-1] in video_extensions: videos.append(os.path.join(root, file)) return videos def get_ffprobe_output(filename: str) -> int: if os.name == 'nt': filename = '"' + filename + '"' else: for char in ' ()[]{}': filename = filename.replace(char, '\\'+char) cmd = 'ffprobe -i {} -show_entries format=duration -v quiet -of csv="p=0"'.format(filename) p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) # output = p.stdout.read().decode().strip() stdout, stderr = p.communicate() return int(float(stdout)) def sec_to_time(sec: int) -> str: s = "%02d:%02d:%02d" % (sec // 3600, sec % 3600 // 60, sec % 60) return s def main(): videos = get_videos() total_duration = 0 for video in videos: duration = get_ffprobe_output(video) print(os.path.split(video)[-1], ' ', sec_to_time(duration)) # or # print(video.split(os.sep)[-1], ' ', sec_to_time(duration)) total_duration += duration print() print('Total duration:', sec_to_time(total_duration)) if __name__ == '__main__': main() [/code]

  • @user-rs5zq9hy4m
    @user-rs5zq9hy4m4 жыл бұрын

    Как всегда отлично подан материал. Спасибо за труд! И куча полезной информации, по всяким мелочам, которые для себя использовать уже можно.

  • @Audi4AA
    @Audi4AA4 жыл бұрын

    Удивительно приятная подача материала! Вас слушать очень интересно! Спасибо за вашу работу! Особенно радуют показанные мелочи, как например, запуск программы из любой папки.

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    Спасибо

  • @digital_ninja
    @digital_ninja3 жыл бұрын

    Олег, очень полезное видео, большое спасибо.

  • @MrYoklmn
    @MrYoklmn4 жыл бұрын

    Ну наконец-то! Ура! Спасибо большое)

  • @NikitaEvd
    @NikitaEvd4 жыл бұрын

    Привет. Наткнулся на ваши курсы по Django. Прекрасно объясняете материал. Хотелось бы различные видео около темы Django: Django Advanced, RESTful API, Celery и так далее. За ваше изложение материала не грех и деньги платить. Благодарю за ваши старания :)

  • @mihailneprostoi6584
    @mihailneprostoi65844 жыл бұрын

    Великолепно как обычно! Спасибо огромное!

  • @Das.Kleine.Krokodil
    @Das.Kleine.Krokodil2 жыл бұрын

    Отличный урок. Последовательно, понятно

  • @1MpresSive1
    @1MpresSive14 жыл бұрын

    Спасибо,жду следующий видос!!!

  • @georgiy_kulagin
    @georgiy_kulagin4 жыл бұрын

    Спасибо, за очередное видео! Есть пара общих вопросов: 1. Будут ли видео по нейронным сетям? Вижу на рабочем столе лежала pdf относящаяся к теме), было бы интересно посмотреть видео от Вас начиная с основ и выше. Хотя возможно был анонс, но я пропутил его... 2. Недавно зарелизили 3.8 пайтон, думаю для многих было бы интересно послушать про новые фичи. Сам еще тот сыч, до сих пор для своих DevOps задач использую 2.7, хотя давно пора уже переезжать, и вот повод вроде появился.

  • @79fz270704
    @79fz2707044 жыл бұрын

    Спасибо Олег, все отлично подано. я где-то видел как получают информацию в json >>> ffprobe -print_format json -show_format -v quiet video.mp4 довольно удобно

  • @igorkulibaba7287
    @igorkulibaba72874 жыл бұрын

    Оооо, повеселее пошли видосы.

  • @user-ny2qu9vw9p
    @user-ny2qu9vw9p Жыл бұрын

    Привет. Канал отличный

  • @sergeykuznetsov4991
    @sergeykuznetsov49914 жыл бұрын

    Спасибо!

  • @niknibud5126
    @niknibud51264 жыл бұрын

    Классное видео. Понял что автоматизация процессов в Windows тот еще гемор, ffmedia (ffprobe) работать не хотел. Но проблему решил через библиотеку pymediainfo.

  • @user-ws6wl5sd2z
    @user-ws6wl5sd2z4 жыл бұрын

    Огонь!

  • @ibrahimoglu
    @ibrahimoglu2 жыл бұрын

    Спасибо.

  • @a.osethkin55
    @a.osethkin55 Жыл бұрын

    Спасибо!!!

  • @rBo3DbHaDoPorE
    @rBo3DbHaDoPorE4 жыл бұрын

    Возможно так будет чуть лучше. Будет более универсальная функция, которая принимает строку(команду) как аргумент + возможность выловить ошибки. def execute(cmd): data = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True) stdout, error = data.communicate() if error: raise RuntimeError(error) return stdout

  • @yakovga
    @yakovga4 жыл бұрын

    Спасибо

  • @daurensdykov9068
    @daurensdykov90684 жыл бұрын

    годнота! спасибо! идея для будущих видео... разработка реальной библиотеки со всем процессом... билд, залив на pypi, возможно тесты и т.д.

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    Библиотеки? Вы еще скажите фреймворк или микросервис. В виде библиотеки - это нафиг никому не нужно. Но в качестве примера для нескольких тем видео - вполне подойдет.

  • @daurensdykov9068

    @daurensdykov9068

    4 жыл бұрын

    @@zaemiel я вообще про библиотеки в целом, а не про эту автоматизацию)

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    понял :)

  • @user-mj9vt8xt2v
    @user-mj9vt8xt2v4 жыл бұрын

    Будет курс по модулю requests на patreon ?

  • @Kindly_Otter
    @Kindly_Otter4 жыл бұрын

    Как актуально для меня оказалось видео, сподвигло всё таки переписать свои скрипты в нормальный вид для более удобного использования :) Кстати, что думаешь насчёт уже стандартного модуля pathlib вместо os для данных целей? Вижу сейчас многие за него агитируют, как за более ООПшный >_> Или это чисто дело вкуса?)

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    Мне кажется, что это дело вкуса.

  • @ankhmarcius8331
    @ankhmarcius83314 жыл бұрын

    осталось узнать как ffprobe сделать внутренней командой системы, что б можно было её вызывать из командной строки таким способом, или же разобраться с библиотеками ffprobe для питона, которые почему то не работают, даже для своих примеров

  • @LOGOSTT
    @LOGOSTT3 жыл бұрын

    Почему не использовали стандартные возможности bash для получения списка файлов с заданным расширением, где это делается в одну строку? А второй строкой получаете искомое. Ради кроссплатформенности?

  • @user-mt6lk8ld7w
    @user-mt6lk8ld7w4 жыл бұрын

    Отличное видео! Вы специально не обновляете свою версию Python?

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    Системный - да, я не обновляю, боюсь что-нибудь сломать. Python 3.6, 3.7 установлены с помощью pyenv - и там путь до интерпретатора сложнее.

  • @aktivigen
    @aktivigen4 жыл бұрын

    топ👏

  • @roberti8506
    @roberti85064 жыл бұрын

    Здравствуйте Олег, вопрос не по теме. Red Eyed Coder Club - это Ваш англоязычный канал?

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    Да

  • @leastexpected3115
    @leastexpected31154 жыл бұрын

    29:05 для разделения полного путя от названия файла можно использовать os.path.split(path_to_file)[-1], так у нас не будет проблем с разными видами слэша (\, /).

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    так ведь нет проблем :) Ладно-ладно... кросплатформенные решения и все такое. Для подобных задач как раз есть модуль pathlib. Спасибо за ваш комментарий.

  • @leastexpected3115

    @leastexpected3115

    4 жыл бұрын

    @@zaemiel Не слышал про эту библиотеку, пойду почитаю про неё. Спасибо

  • @Das.Kleine.Krokodil
    @Das.Kleine.Krokodil2 жыл бұрын

    17:40 почему именно popen, а не run или что то другое из этого модуля?

  • @Das.Kleine.Krokodil
    @Das.Kleine.Krokodil2 жыл бұрын

    30:55 в чем преимущество такого импортирования отдельной функции, а не всего модуля?

  • @Bobronium
    @Bobronium4 жыл бұрын

    Спасибо за видео! 13:20 - здесь корректнее было бы использовать file.rsplit('.', maxsplit=1), так как в имени файла может быть несколько точек. А ещё в os.path есть функция splitext, которая делает то же самое.

  • @FogerSP

    @FogerSP

    4 жыл бұрын

    Я может не понял: так он то же самое делает с помощью file.split('.')[-1] - берет последнее значение из списка, который сделал с помощью split('.') - то есть расширение файла, оно всегда будет последним. Может вы имели ввиду что rsplit быстрее работает, ведь он с конца идет и сразу получает расширение получается. UPD: как ни странно, но в моем случае скрипт с file.split('.')[-1] обходит чуть быстрее чем с file.rsplit('.', maxsplit=1)[1]

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    Мне нравится, что вы видите и другие решения. Это прекрасно.

  • @79fz270704

    @79fz270704

    4 жыл бұрын

    есть же splitext() >>> import os >>> filename, file_extension = os.path.splitext('/path/to/somefile.ext')

  • @Bobronium

    @Bobronium

    4 жыл бұрын

    @@FogerSP да, вы правы, в данном контексте оно будет работать так же. Но если бы понадобилось имя файла, такой способ уже бы не подошел.

  • @Bobronium

    @Bobronium

    4 жыл бұрын

    @@79fz270704 я упомянул это в конце комментария :)

  • @user-os1xg1rh4c
    @user-os1xg1rh4c Жыл бұрын

    Понятно, что писалось 3 года назад и т.д. и т.п. Тем не менее, хорошо бы посмотреть на обновленный код, где вы разбираете свои же костыли. Например, проход по файлам с помощью glob, lambda вместо seconds to str, python код для ff вместо дерганья subprocess, ну и для «взрослых» threads, т.к. одна и та же функция работает над последовательностью файлов и порядок их следования не важен.

  • @alexanderpadalka5708
    @alexanderpadalka57083 жыл бұрын

    🗽

  • @DrublChannel
    @DrublChannel4 жыл бұрын

    Олег, прорекламируй свои курсы

  • @alexeysavostin
    @alexeysavostin4 жыл бұрын

    Добрый день! Вопрос по вашему курсу, Олег. На патрионе - 10$/месяц. Что это значит? Есть ли там возможность сохранять видео для повторного просмотра?

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    Это значит, что вы донаните 10$ и в течение месяца имеет доступ ко всем материалам на Patreon. Курс пока только один. Возможности сохранить видео, насколько я понимаю, там нет.

  • @The_One_Channel
    @The_One_Channel4 жыл бұрын

    Ты где то работаешь или фриланс?

  • @amicus9692
    @amicus96924 жыл бұрын

    Не могли бы вы подсказать, как сделать регистрацию и мгновенный вход после этого в django 2.x .

  • @evalinor

    @evalinor

    4 жыл бұрын

    def reg(request): if request.method == "POST": form = UserRegisterForm(request.POST) if form.is_valid(): form.save() username = form.cleaned_data['username'] password = form.cleaned_data['password1'] user = authenticate(username = username, password = password) login(request,user) UserAttribute.objects.create(silver_coin = 1000, knights = 75, power = 85, level = 1, xp = 0, energy = 100, totalWin = 0, user_id = user.id) return redirect('/welcome') else: form = UserRegisterForm() return render(request,'register.html',{'form':form})

  • @evalinor

    @evalinor

    4 жыл бұрын

    и в settings.py добавить "LOGIN_REDIRECT_URL = '/welcome'", где 'welcome/' - нужная тебе страница после регистрации

  • @Das.Kleine.Krokodil
    @Das.Kleine.Krokodil2 жыл бұрын

    17:45 почему же списком будет безопаснее?

  • @user-lq3qe7ji9b
    @user-lq3qe7ji9b Жыл бұрын

    Приветствую. Куда вы пропали?) Многие ждут ваших выпусков

  • @zaemiel

    @zaemiel

    Жыл бұрын

    занят зарабатыванием денег

  • @dmitriy2502
    @dmitriy25022 жыл бұрын

    Здравствуйте! Подскажите почему выдет такое: File "C:\Python\lib\encodings\cp1251.py", line 19, in encode return codecs.charmap_encode(input,self.errors,encoding_table)[0] UnicodeEncodeError: 'charmap' codec can't encode character '\u049a' in position 3832: character maps to

  • @user-gf9qw3tv9m
    @user-gf9qw3tv9m4 жыл бұрын

    Здравствуйте, вопрос не по теме но все же, а что у вас за оверлей в правом нижнем углу экрана можете поделиться? Сам минтом пользуюсь и захотелось имать такое тоже)

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    Это называется Conky. Я настраивал его через Conky Manager, который запускается при старте системы (ресурсов потребляет чуть-чуть). Вам придется погуглить как его настраивать, но вроде не сложно. Настройки мои такие: ${offset 30}${color FFA300}CPU ${offset 9}$color${cpu cpu0}% ${offset 30}${color FFA300}RAM ${offset 9}$color$mem / $memmax Вы, конечно же, увидите более навороченные варианты, но мне не к чему, поэтому только две строки.

  • @user-gf9qw3tv9m

    @user-gf9qw3tv9m

    4 жыл бұрын

    @@zaemiel спасибо) Это не проблема мне тоже нужно эти две строки, спасибо)

  • @garrygoodrege255
    @garrygoodrege2554 жыл бұрын

    Олег не подумай ничего плохого, хоть я и мужик но тембр голоса у тебя классный, я блин под него залипаю на видосе, но за твой труд спасибо тебе...продолжай пожалуйста, есть небольшое пожелание, возможно ли примеры с ветвления (ход работы if-else и циклы но с привязкой н-р к реальности типа скачать папку откуда либо, или список файлов.

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    Спасибо. По вашей просьбе в базовом курсе будут "лабы"-проекты с подобными объяснениями.

  • @vladdudmmm5493
    @vladdudmmm54934 жыл бұрын

    Подскажите дистрибутив линукса который используете.

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    Это Linux Mint

  • @vladdudmmm5493

    @vladdudmmm5493

    4 жыл бұрын

    @@zaemiel спасибо

  • @xtreitd
    @xtreitd4 жыл бұрын

    Подскажите пожалуйста, почему может быть такая ошибка? /bin/sh: 1: ffprobe: not found

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    Написано, что "ffprobe не найден" Я тут упоминал, что ffprobe идет в поставке с ffmpeg. Вам нужно установить ffmpeg. Для *deb дистрибутивов: sudo apt-get install ffmpeg

  • @xtreitd

    @xtreitd

    4 жыл бұрын

    @@zaemiel а я видимо не внимательно но слушал :)

  • @Ooshka
    @Ooshka4 жыл бұрын

    подскажите кто шарит, скачал проект на python, как узнать какая версия python для него нужна?

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    должно быть указано либо в README.md либо шибанги могут быть. Вообще вариантов только 2 - это 2.7 и 3. Установите в виртуальное окружение Python3, активируйте его. И пробуйте. Если есть файл requirements.txt (это файл с перечисленными зависимостями), то из активированного окружения выполните команду: pip install -r requirements.txt

  • @ThePirateHistory
    @ThePirateHistory4 жыл бұрын

    endswitch не?

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    я не понял

  • @karlzinher4181
    @karlzinher41814 жыл бұрын

    49 из 122 комментов :) всего за один день :) ... прям сериал...

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    мы старались :) Да, такая драма развернулась. Честно говоря, не думал, что до такого дойдет.

  • @karlzinher4181

    @karlzinher4181

    4 жыл бұрын

    @@zaemiel сериал пришлось досрочно свернуть, по причине не способности оплатить гонорар главному герою :D

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    Он считает, что он прав. С этим трудно что-то сделать. Может быть это привычка смотреть на вещи с позиции начальника.

  • @karlzinher4181

    @karlzinher4181

    4 жыл бұрын

    @@zaemiel Я сомневаюсь, что Антон руководитель (хотя это не так принципиально) Он изначально "прослушал" видео невнимательно о том, что будет серия видео (в том числе и многопоточном варианте кода) И на протяжении всего общения пропускал мимо ушей информацию ... "фильтры" в ушах наверное :) Но было интересно. Заодно посмотре чем человек занимается на гитхабе :) коммиты говорят сами за разработчика.

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    на самом деле его гитхаб ни о чем не говорит. Он мог пользоваться битбакетом или гитлабом и комитить в приватные репозитории. Но думаю, что вы правы - он не очень похож на руководителя. Функциональный подход, который вовсе не функциональный, дублирование кода, чрезмерно усложненный код, когда в этом нет необходимости - слишком очевидны. Хотя использование shlex.quote() для экранирования имен файлов мне понравилось. Еще мне показалось странным, что он использует gc, но не использует контекстный менеджер with для работы с Pool'ом, хотя он его поддерживает.

  • @dv7045
    @dv70454 жыл бұрын

    что на счет udemy ?

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    я буду думать. У них есть проблемы (минусы, подвоные камни и прочие эпитеты и метафоры. Пока тестирую эту идею.

  • @DzedunMao

    @DzedunMao

    4 жыл бұрын

    @@zaemiel на udemy б курс купил.

  • @FogerSP
    @FogerSP4 жыл бұрын

    Скобки в имени файла, если есть, тоже нужно экранировать, иначе будет unexpected token `(

  • @FogerSP

    @FogerSP

    4 жыл бұрын

    можно просто re.escape(filename)

  • @FogerSP

    @FogerSP

    4 жыл бұрын

    и return int(float(stdout)) вместо точного значения из ffprobe при большом количестве файлов, фильмов например, - разница будет в несколько минут от реальной длительности

  • @zaemiel

    @zaemiel

    4 жыл бұрын

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

  • @yodapunishes
    @yodapunishes4 жыл бұрын

    Почему бОш, он же бЭш?)

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    да, он бэш

  • @Kindly_Otter

    @Kindly_Otter

    4 жыл бұрын

    всегда звал его бАшем :)

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    да, но читается-то бЭш

  • @KvantVS
    @KvantVS2 ай бұрын

    Почему "бОш"? А не бАш или бЭш?

  • @zaemiel

    @zaemiel

    2 ай бұрын

    потому что я произносил это слово неправильно

  • @as-1973
    @as-19734 жыл бұрын

    Не совсем понял зачем вам это считать, но если вы не знакомы с таким редактором как Adobe Premier, то наверное стоит немного погуглить)))

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    По-моему, это самый смешной комментарий на всем канале. Я не знаком с таким редактором и, честно говоря, не вижу смысла знакомиться.

  • @keepsilence6843
    @keepsilence68434 жыл бұрын

    Кто диз влепил? Залетный php-шник?

  • @zaemiel

    @zaemiel

    4 жыл бұрын

    Спасибо большое за поддержку. Я это очень ценю и если бы не вы я бы уже давно все бросил бы. Честное слово. По поводу стримов - не знаю, что тут можно делать... просто не понимаю, что можно стримить.

  • @karlzinher4181

    @karlzinher4181

    4 жыл бұрын

    Keep :^) ваи бы в юмористы пойти......

  • @sainco3036
    @sainco30364 жыл бұрын

    Спасибо.

Келесі