繁体   English   中英

Makefile:如何在 shell 块内使用循环值

[英]Makefile: How to use a loop value inside a shell block

鉴于以下目录结构...

my-project
    + frames
         + frame-1.jpg
         + frame-2.jpg
         ...
         + frame-200.jpg
    + locales
         + default
         |   + music.mp3
         + en
             + music.mp3

对于目录localesdefaulten )中的每个语言环境,我需要:

  • 调用ffprobe以确定音频文件 ( *.mp3 ) 的DURATION时间(以秒为单位);
  • 确定形成最终视频的jpg帧数,用于所有语言环境;
  • 计算帧FRAMERATEFRAMERATE = 1 / (DURATION / FRAMES) );
  • 调用ffmpeg使用计算的FRAMERATEjpg帧和音频文件创建 mp4 视频。

下面是我的Makefile的摘录:

.DEFAULT_GOAL := build

FRAMES_DIR := ${CURDIR}/frames
LOCALES_DIR := ${CURDIR}/locales
OUTDIR:= ${CURDIR}/build

.PHONY: build

build:
    @for dir in $(shell find $(LOCALES_DIR) -type d -depth 1 -exec base name {} \;); do
        $(eval DURATION := $(shell ffprobe -v error -show_entries format=duration -of \
            default=noprint_wrappers=1:nokey=1 $(LOCALES_DIR)/$$dir/*.mp3)); \
        $(eval FRAMES := $(shell ls $(FRAMES_DIR) | wc -l))
        $(eval FRAMERATE := $(shell awk "BEGIN {print 1 / ($(DURATION) / $(FRAMES))}"))
        ffmpeg -y -framerate $(FRAMERATE) -start_number 1 -i $(FRAMES_DIR)/frame_%d.jpeg -i $(LOCALES_DIR)/$$dir/*.mp3 \
           -c:v libx264 -pix_fmt yuv420p -c:a aac -strict experimental \
           -shortest $(OUTDIR)/$video-$$dir.mp4; \
    done;

这是预期的结果:

my-project
    + build
         + video-default.mp4
         + video-en.mp4

问题是ffprobe命令失败,因为输入路径错误,即$$dir不包含预期的子目录名称( defaulten )。 长话短说,似乎$$dir$(shell...)内不可见。

我错过了什么吗? 谢谢。

尝试使用多行 shell 脚本,如下所示:

build:
    find "${LOCALES_DIR}" -type d -depth 1 -exec base name {} \; | while read -r dir; \
    do \
        DURATION="$$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "${LOCALES_DIR}/$$dir"/*.mp3)"; \
        FRAMES="$$(ls -1 "$$FRAMES_DIR" | wc -l)"; \
        FRAMERATE="$$(awk "BEGIN {print 1 / ($$DURATION / $$FRAMES)}")"; \
        ffmpeg -y -framerate "$$FRAMERATE" -start_number 1 -i "$$FRAMES_DIR"/frame_%d.jpeg -i "${LOCALES_DIR}/$$dir"/*.mp3 \
               -c:v libx264 -pix_fmt yuv420p -c:a aac -strict experimental \
               -shortest "${OUTDIR}"/$$video-"$$dir".mp4 < /dev/null; \
    done;

我做了一些改变:

  • 我使用了一个while read循环来避免带有空格的路径问题
  • 我将-1添加到ls以便每个项目都打印在自己的行上,这应该确保wc -l给出准确的计数
  • 我将/dev/null作为标准输入重定向到ffmpeg以便ffmpeg不会干扰while read循环

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM