-
Notifications
You must be signed in to change notification settings - Fork 0
/
a2v
executable file
·106 lines (89 loc) · 3.53 KB
/
a2v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/env fish
# a2v - "Audio to video". Create a video from an image and audio file.
# Useful for when you want to upload music to YouTube or other video sharing sites.
# Note: at the moment, the image file can't be a gif.
# Also note: The larger the image file size, the longer it will take to generate the video.
# Usage:
#
# a2v <IMAGE> <AUDIO> [OUTPUT]
# Or:
# a2v <-i IMAGE> <-a AUDIO> [-o OUTPUT]
# Examples:
#
# Use cover.jpg as the image and happybirthday.mp3 as the audio file. the output file will be 'happybirthday.mp4' in the current directory:
# a2v cover.jpg happybirthday.mp3
#
# Use cover.jpg as the image, happybirthday.mp3 as the audio file, and dmca.ogv as the output filename:
# a2v cover.jpg happybirthday.mp3 dmca.ogv
#
# Use blah.png as the image, foobar.mp3 as the audio, and nice.mp4 as the filename of the resulting video:
# a2v -i blah.png -a foobar.mp3 -o nice.mp4
# code:
# FIX: make the image file optional; if not provided, just create the video fully black.
# FIX: handle gifs. this may be possible, or perhaps we create a temporary copy in png format.
set -- script "$(path basename (status filename))"
argparse -n $script 'i/image=' 'a/audio=' 'o/output=' 'h/help' -- $argv
if set -q _flag_h
echo "$script - Create a video from an image and audio file."
echo "Usage: $script [arguments] [-i] image [-a] audio [[-o] output]"
echo
echo " -h/--help - Show this help and exit."
echo " -i/--image - The image file to use as the video's visual component."
echo " -a/--audio - The audio file to use as the video's aural component."
echo " -o/--output - The output filename. The video format is determined by the extension. If not specified, the output filename is the same as the audio file, but with its extension changed to mp4."
end
if not command -qs ffmpeg
echo "$script: Error: ffmpeg not found in PATH." >&2
exit 2
end
set image "$_flag_i"
set audio "$_flag_a"
set output "$_flag_o"
if test -z "$image"
set image $argv[1]
if test -z "$image"
echo "$script: Error: An image is required (first argument or -i)." >&2
exit 1
end
if not test -f "$image"
echo "$script: Source image '$image' not found." >&2
exit 1
end
set argv $argv[2..]
end
if test -z "$audio"
set audio $argv[1]
if test -z "$audio"
echo "$script: Error: An audio file is required (second argument or -a)." >&2
exit 1
end
if not test -f "$audio"
echo "$script: Source audio '$audio' not found." >&2
exit 1
end
set argv $argv[2..]
end
if test -z "$output"
set output $argv[1]
if test -z "$output"
set output (string split -m 1 -r '.' "$audio")[1]".mp4"
echo "$script: Assuming output filename '$output'." >&2
end
set argv $argv[2..]
end
if not command -qs ffprobe
echo "$script: Error: ffprobe not found in PATH." >&2
exit 2
end
set length (ffprobe -i "$audio" -show_entries format=duration -loglevel quiet -of csv="p=0")
if test -f "$output"
if ask-yes-no --default=1 "Output file '$output' already exists; overwrite?"
echo "$script: Overwriting '$output'." >&2
else
echo "$script: Operation canceled." >&2
exit 1
end
end
# -c:v libx264 -crf 20 -preset slow -vf format=yuv420p -c:a aac -movflags +faststart output.mp4
# ffmpeg -i "$audio" -loop 1 -i "$image" -r 1 -shortest -t $length "$output"
nice -n 10 ffmpeg -y -i "$audio" -loop 1 -i "$image" -r 1 -shortest -t $length -c:v libx264 -crf 20 -preset slow -vf format=yuv420p -c:a aac -movflags +faststart "$output"