Add Advertisement on a bunch of videos

Task: In order to advertise a company, I have to download a bunch of(1000 or so) videos related to the company from Youku, then add title sequence and watermark(or say subtitles), finally upload all of them to Youku.

I’ve tried Adobe Premiere, OpenCV, and finally use ffmpeg and python to accomplish this task.

Here is how I hacked the task.

Download Videos

  1. Find the video I want to download.
  2. Use flvcd to get the downloadable link.
  3. Download it.

I have to do 1 to 3 in loop, so I write python script to do this.

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
import urllib2
import urllib
import re

# get_url_content can return the html text of given url. It comouflage my python program as a browser.
def get_url_content(url):
i_headers = {"User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1) Gecko/20090624 Firefox/3.5",\
"Referer": 'http://www.baidu.com'}
req = urllib2.Request(url, headers=i_headers)
return urllib2.urlopen(req).read()

fopen = open('result.py','r') #result.py contains video links in python syntax.
result = fopen.read()
urls = eval(result) # transform string into python object

for url in urls:
title = url['title']
href = url['href']
flvcd_url = 'http://www.flvcd.com/parse.php?kw=' + href
html = get_url_content(flvcd_url)

# use regular expression to extract downloadable links
download_urls = re.findall(r'href="http://k.youku.com/player/getFlvPath/sid/[.\S]+', html)

# because some video is divided into several part, so I use for loop to download them respectively by using urllib.urlretrieve().
for i in range(0, len(download_urls)):
urllib.urlretrieve(download_urls[i][6:], './videos/'+title+str(i)+'.flv')

Edit videos

Adobe Premiere

Adobe Premiere is one of the most powerful video edit tools. It works very well on generating single output. However, we have to deal with a thousand videos repeatedly, it would be time consuming.

Computer does repeated things better than human, so I try to write lines of program to do that, and here is my attempts:

OpenCV

OpenCV is a library of programming functions mainly aimed at real-time computer vision and it contain a video session. However it deal with video well but it save without audio, so it cannot work in this task.

ffmpeg

Later, I found ffmpeg, which perfectly suit this task.

This is ffmpeg script running in terminel:

ffmpeg [global_options] {[input_file_options] -i input_file} ... {[output_file_options] output_file} ...

Here I list the commends I used in edit videos.

change the size of a video:

ffmpeg -i input.mkv -s 512x288 output.mkv

concatenate two videos(the two videos should have the same size, SAR and so on)

ffmpeg -i head.mp4 -i output.mkv -filter_complex "[0:0] [0:1] [1:0] [1:1] concat=n=2:v=1:a=1 [v] [a]" -map "[v]" -map "[a]" output-cat.mkv

add watermarks:

ffmpeg -i output-cat.mp4 -itsoffset 00:00:05 -t 00:00:08 -i title.png -filter_complex  '[1:v]scale=400:100[s];[0:v][s]overlay=0:main_h-overlay_h' output-mark.avi

the time after -itsoffset denotes when the mark star to appear, the time after -t is suppose to denote the duration, but it doesn’t work for picture; size of mark(scale = 400:100); position(overlay=10:10), 0:0 denotes leftup, and main_w-overlay_w:main_h-overlay_h denotes right button.

Since watermark cannot appear for a while and hide for a while, I need other way to present the advertisement, and here comes the subtitle.

add subtitle:

ffmpeg -i output-cat.mp4 -i test.srt -map 0:0 -scodec copy -map 1:0 -vcodec copy -map 1:1 -acodec copy output-sub.avi

python again

All of the commend works on single output, so I turn to python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import os

work_dir = './videos/'
videos = os.listdir(work_dir)

# concatenate head: 1. resize flv as -resize.mkv, 2. concatenate 3. add .srt
for video in videos:
# result = os.popen('ffmpeg -i ' + work_dir + video + ' -i ./head.mp4 ' + work_dir +'combined/' + video[:-4] + 'combined.mp4')
result = os.popen('ffmpeg -i '+work_dir + video +' -s 512x288 '+work_dir +video[:-4]+'-resized.mkv')
print result
result = os.popen('ffmpeg -i ./head.mp4 -i '+work_dir + video[:-4]+'-resized.mkv -filter_complex "[0:0] [0:1] [1:0] [1:1] concat=n=2:v=1:a=1 [v] [a]" -map "[v]" -map "[a]" ' + work_dir +'combined/' + video[:-4] + 'combined.mp4')
print result
# os.popen('rm '+work_dir +video[:-4]+'-resized.mkv')

videos = os.listdir(work_dir+'combined/')
for video in videos:
result = os.popen('ffmpeg -i ' + work_dir + video + ' -i test.srt -scodec copy ./' + work_dir + video[:-4] + 'added.mkv')
print result

Here we should have done the task. However, the video I downloaded are in various size and SAR. It seems has no function to ajust SAR directly, so this program has some flaws.

Finally I find what I was doing is recreate wheel, that is there is already a robust software can do this task. 那个软件叫“音影转霸”,可以在这里下载。

Reference