audio_to_youtube 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +30 -0
  3. metadata +3 -2
  4. data/lib/audio_to_youtube.rb +0 -326
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 222b2488455a1f11c03853d3772db05f473aab73
4
- data.tar.gz: 3d62868b920f7e694913b8cec93eff7b6e8a9b83
3
+ metadata.gz: c0e35ed366d88adb022bc5936ad38c8815b46d71
4
+ data.tar.gz: c81453f21b04751372ffbbd3b79be4527e3cc3ea
5
5
  SHA512:
6
- metadata.gz: 80e4dad589ee2596966310100151262afbe3f486c767159581ebbbcb1032b76ad803851c27ecbab33f8ad7718ba6955c16ff65b602722eb2a273d2a694d3ecc0
7
- data.tar.gz: 96eac8616a78146fb75764e391fb6e8f5045a14d07ca8d156cf16c2d64d37ac07e04e03ac3269f529c41f7b0622cc1d5e2c738e64b23d5fff65ebde65be8db9b
6
+ metadata.gz: 354cdcedabc8cc38e4168c2117cc96b37a438e13b8f2172fcbbb1049cf49018fa5746a30d386d743392a95e75f8c128007fff1bae933171fce17b78ec0cf7500
7
+ data.tar.gz: efde833ca0241f0b6a11415d7e5e3f1313746c608be69b62ac8335823130262c48febe40ea8862cc048c1a8a5fbf9f95ab7092881017dd2cbedd2670c43d36a6
@@ -0,0 +1,30 @@
1
+ = Audio to youtube
2
+ Convert audio with background image to mp4 for uploading to youtube using ffmpeg.
3
+
4
+ Based on a python script: https://github.com/ianharmon/mp3-to-youtube
5
+
6
+ == Install
7
+
8
+ gem install audio_to_youtube
9
+
10
+ == Usage
11
+
12
+ require 'audio_to_youtube'
13
+ AudioToYoutube.generate audio, background, out
14
+
15
+
16
+ == Description
17
+ * *audio*: audio file name with path
18
+
19
+ * *background*: static background for the output video (will use *bg.jpg* if not specified)
20
+
21
+ * *out*: output filename (will use *out.mp4* as default)
22
+
23
+ == License
24
+ Copyright (C) 2015 *Brian Doan*
25
+
26
+ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
27
+
28
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
29
+
30
+ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: audio_to_youtube
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Doan
@@ -16,7 +16,7 @@ executables: []
16
16
  extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
- - lib/audio_to_youtube.rb
19
+ - README.rdoc
20
20
  homepage: http://rubygems.org/gems/audio_to_youtube
21
21
  licenses:
22
22
  - MIT
@@ -42,3 +42,4 @@ signing_key:
42
42
  specification_version: 4
43
43
  summary: Convert audio with background image to mp4 for uploading to youtube
44
44
  test_files: []
45
+ has_rdoc:
@@ -1,326 +0,0 @@
1
- class AudioToYoutube
2
- @outputFile = 'out.mp4'
3
- @tempFolder = 'temp'
4
- @tempBg = 'bg.jpg'
5
- @backgroundBase = 'media/bg-720.png'
6
- @ffmpegDir = 'setme'
7
- @imagemagickDir = 'setme'
8
- private
9
- def self.exitWithError(message)
10
- puts ('\nError: ' + message)
11
- end
12
-
13
- ################################################################################
14
- # Generates the background art for the video
15
- def self.generateBackground(audio, backgroundBase, output, blur, text)
16
-
17
- blur ||= false
18
- text ||= ""
19
-
20
- # extract the album art
21
- tempArt = "#{Dir.pwd}/art.png"
22
- cmd = ["ffmpeg"]
23
- cmd += ['-y']
24
- cmd += ["-i #{audio}"]
25
- cmd += ['-acodec none']
26
- cmd += [tempArt]
27
- puts 'Extracting album art...'
28
- begin
29
- unless Dir.exist?(@tempFolder) ||
30
- Dir.mkdir(@tempFolder)
31
- puts p cmd.join(' ')
32
- end
33
- rescue
34
- exitWithError('Couldn\'t find album art in the audio file. ' +
35
- 'Use the -background option to select an image file.')
36
- end
37
-
38
- # now, build the background image
39
- cmd = ["imagick"]
40
- cmd += [backgroundBase]
41
-
42
- # draw the blurred album art background
43
- if blur
44
- cmd += ['-gravity', 'center']
45
- cmd += ['(']
46
- cmd += [tempArt]
47
- cmd += ['-resize', '1500x']
48
- cmd += ['-modulate', '90']
49
- cmd += ['-blur', '0x20']
50
- cmd += [')']
51
- cmd += ['-composite']
52
- end
53
-
54
- # set offsets depending on whether text is drawn
55
- gravity = 'center'
56
- offset = []
57
- shadowOffset = []
58
- unless text.empty?
59
- gravity = 'west'
60
- offset = ['-geometry', '+60+0']
61
- shadowOffset = ['-geometry', '+30+0']
62
- end
63
-
64
- # set some settings used twice
65
- mainArtFront = ['(']
66
- mainArtFront += [tempArt]
67
- mainArtFront += ['-resize', 'x720']
68
-
69
- mainArtBack = [')']
70
- mainArtBack += ['-gravity', gravity]
71
- mainArtBack += ['-composite']
72
-
73
- # draw shadow of the main album art
74
- cmd += mainArtFront
75
- cmd += ['-background', 'black']
76
- cmd += ['-shadow', '50x15+0+0']
77
- cmd += shadowOffset
78
- cmd += mainArtBack
79
-
80
- # draw the main album art
81
- cmd += mainArtFront
82
- cmd += offset
83
- cmd += mainArtBack
84
-
85
- # add in the track metadata text
86
- unless text.empty?
87
- labelText = text[0]
88
- for i in 1..text.length
89
- labelText += '\\n\\n' + text[i]
90
- end
91
-
92
- # set some settings used twice
93
- labelFront = ['(']
94
- labelFront += ['-size', '440x400']
95
- labelFront += ['-background', 'none']
96
- labelFront += ['-gravity', 'center']
97
- labelFront += ['-font', 'Segoe-UI-Semibold']
98
-
99
- labelMid = ['caption:' + labelText]
100
-
101
- labelBack = ['-geometry', '+25+0']
102
- labelBack += [')']
103
- labelBack += ['-gravity', 'east']
104
- labelBack += ['-composite']
105
-
106
- # draw text shadow
107
- cmd += labelFront.join(' ')
108
- cmd += ['-fill', '#00000090']
109
- cmd += labelMid.join(' ')
110
- cmd += ['-blur', '0x6']
111
- cmd += labelBack.join(' ')
112
-
113
- # draw text itself
114
- cmd += labelFront.join(' ')
115
- cmd += ['-fill', 'white']
116
- cmd += labelMid.join(' ')
117
- cmd += labelBack.join(' ')
118
-
119
- end
120
-
121
- # put it all together
122
- cmd += [output]
123
- puts 'Generating video background...'
124
- begin
125
- puts Open3.capture3(cmd.join(' '))
126
- rescue
127
- exitWithError('Something went wrong when generating the background.')
128
- end
129
- end
130
-
131
- ################################################################################
132
- # Splits text over multiple lines
133
- def self.splitText(text, maximumLength)
134
-
135
- maximumLength ||= 20
136
- words = text.split(' ')
137
- output = ''
138
- currentLine = ''
139
- words.each do |word|
140
- if currentLine == ''
141
- currentLine = word
142
- else
143
- temp = currentLine + ' ' + word
144
- # with next word, still under maximum length - add normally
145
- if len(temp) < maximumLength
146
- currentLine = temp
147
- # next word is longer than the maximum length - it gets its own line
148
- elsif len(word) > maximumLength
149
- if output != ''
150
- output += r'\n'
151
- end
152
- output += currentLine
153
- currentLine = ''
154
- if output != ''
155
- output += r'\n'
156
- end
157
- output += word
158
- # we've overrun the maximum length - start a new line with the word
159
- else
160
- if output != ''
161
- output += 'r\n'
162
- end
163
- output += currentLine
164
- currentLine = word
165
- end
166
- end
167
- end
168
- if output != ''
169
- output += r'\n'
170
- end
171
- output += currentLine
172
- #print(output)
173
- return output
174
- end
175
-
176
- ################################################################################
177
- # Retrieves the title and artist from the file
178
- def self.getMetadata(file)
179
- cmd = ["ffprobe"]
180
- cmd += ['-i', file]
181
- print('Extracting metadata...')
182
- lines = ""
183
- begin
184
- output = p cmd.join(' ')
185
- lines = output.split('\n')
186
- rescue
187
- exitWithError('Couldn\'t extract metadata from the file.')
188
- end
189
-
190
- title = ""
191
- artist = ""
192
-
193
- lines.each do |line|
194
- match = line.scan(/^\s*(.*?)\s*: (.*?)\s*@/)
195
- if match.length > 0
196
- pair = match[0]
197
-
198
- if len(pair) == 2
199
- if pair[0] == 'title' and pair[1].length > 0
200
- if title == "" # or len(title) < len(pair[1]):
201
- title = pair[1]
202
- print("Found title: " + title)
203
- end
204
- elsif pair[0] == 'artist' and pair[1].length > 0
205
- if artist == "" # or len(artist) < len(pair[1]):
206
- artist = pair[1]
207
- print("Found artist: " + artist)
208
- end
209
- end
210
- end
211
- end
212
- end
213
- return artist, title
214
- end
215
- ################################################################################
216
- # Creates the final video suitable for uploading
217
- def self.encode(audio, background, output)
218
- cmd = ["ffmpeg"]
219
- cmd += ['-y']
220
- cmd += ['-loop', '1']
221
- cmd += ['-r', '1']
222
- cmd += ['-i', background]
223
- cmd += ['-i', audio]
224
- cmd += ['-c:v', 'libx264']
225
- cmd += ['-preset', 'veryfast']
226
- cmd += ['-tune', 'stillimage']
227
- cmd += ['-crf', '15']
228
- cmd += ['-pix_fmt', 'yuv420p']
229
- cmd += ['-strict', 'experimental']
230
- cmd += ['-c:a', 'aac']
231
- cmd += ['-b:a', '256k']
232
- cmd += ['-shortest']
233
- cmd += ['-threads', '0']
234
- cmd += [output]
235
- print('Encoding video...')
236
- begin
237
- system(cmd.join(' '))
238
- rescue
239
- exitWithError('Something went wrong when encoding the video.')
240
- end
241
- print('\nDone. Saved output as "%s".' % @outputFile)
242
- end
243
-
244
- ################################################################################
245
- # Set library locations
246
- def self.setLibraryLocations()
247
-
248
- # set FFmpeg location
249
- if @ffmpegDir == 'setme' or @ffmpegDir == ''
250
- @ffmpegDir = '/usr/local/bin'
251
- end
252
-
253
- # set ImageMagick location
254
- if @imagemagickDir == 'setme' or @imagemagickDir == ''
255
- @imagemagickDir = '/usr/local/bin'
256
- end
257
-
258
- # set full paths
259
- ffprobe = Dir.pwd + " " + @ffmpegDir + ' ffprobe'
260
- ffmpeg = Dir.pwd + " " + @ffmpegDir + ' ffmpeg'
261
- imagick = Dir.pwd + " " + @imagemagickDir + ' convert'
262
-
263
- # ensure libraries are actually installed
264
- unless (os.path.exists(ffprobe) and os.path.exists(ffmpeg))
265
- exitWithError("FFmpeg couldn\'t be found at \"#{@ffmpegDir}\". " +
266
- 'Please check your configuration.')
267
- end
268
- unless os.path.exists(imagick)
269
- exitWithError("ImageMagick couldn\'t be found at \"#{@imagemagickDir}\". " +
270
- 'Please check your configuration.')
271
- end
272
- end
273
- public
274
- ################################################################################
275
- # Program entrypoint.
276
- def self.generate *args
277
- audio = nil
278
- bg = nil
279
- out = nil
280
- if args.size < 1 || args.size > 3
281
- puts 'This method takes either 1 to 3 arguments'
282
- else
283
- audio = args[0]
284
- if args.size == 2
285
- bg = args[1]
286
- elsif args.size == 3
287
- bg = args[1]
288
- out = args[2]
289
- end
290
- end
291
-
292
- bg ||= @tempBg
293
- out ||= @outputFile
294
- unless File.exist?(audio)
295
- exitWithError("Input file \"#{audio}\" doesn\'t exist or can\'t be read.")
296
- end
297
-
298
- # determine arguments
299
- custom = bg
300
- doBlur = true
301
- doText = false
302
-
303
- background = Dir.pwd + " " + @tempFolder + " " + bg
304
-
305
- # grab metadata if necessary
306
- text = ""
307
- if doText and custom == ""
308
- metadata = getMetadata(audio)
309
- metadata.each do |item|
310
- if item != ""
311
- #split = splitText(item)
312
- text.append(item)
313
- end
314
- end
315
- end
316
-
317
- # generate the background unless a premade one is specified
318
- if custom == ""
319
- generateBackground(audio, backgroundBase, background, blur=doBlur, text=text)
320
- else
321
- background = custom
322
- end
323
- encode(audio, background, out)
324
- end
325
-
326
- end