← All posts

Weekend project: Build an automated YouTube Channel

TLDR: Made a fully automated music YouTube channel. Worked for a while, had lots of views, then got disabled by YouTube.

You can't miss it. Today, the trend on YouTube is for static music videos with beautiful girls or landscapes. With the channel logo upfront.

I wanted to see if it was possible to create this kind of channel, fully automated with just a Python script.

The first step is to find a music source.

I wanted to find tracks not yet popular on YouTube but with a clear public interest.

I settled on the "Popular Now" playlist on Hype Machine. This was perfect as HypeMachine already as an API, so no need to go scrape the website.

Then, I needed elements to create the static image associated with the music.

For the background image, Unplash was the obvious choice. I created a collection of ~200 images that would fit for the videos. I would then only need to fetch a random one with https://source.unsplash.com/collection/<collectionid>/1920x1080.

I also needed my logo to be put on each video, so I made a quick one.

Here is what it would like at the end, after a quick merge:

Neat right?

I then created a folder for every channel I wanted to automate.
This allow me to easily add more channels, in less than 5 minutes.

creds.json contains the channel's oAuth token needed to upload videos to YouTube.

info.json is a very simple file containing some needed infos for the script:

    "name": "Chill Ocean","image": "https://source.unsplash.com/collection//1920x1080",
    "hypem": ["https://api.hypem.com/v2/popular?mode=now&count=10"]

Finally, res/titlelayer.png is the channel's logo to be merged.

Now the Python script.

I decided to use MoviePy to build the video, and youtube-upload to send it to YouTube.

from termcolor import colored
from moviepy.editor import *
import json, requests, urllib, os, sys, os.path


def createVideo(channel, image, title, artist, itemid, audio_url):

	uploaded_location = "/home/vince/Dropbox/Applications/"+channel+"/uploaded.txt"

	name = artist+' - '+title

    # Check in the synced text file if we already uploaded this song
    if itemid in open(uploaded_location).read():
        print name + colored(" -> Already uploaded", 'green')
        print name + colored(" -> Let's upload", 'magenta')


        print 'Downloading audio...'
        urllib.urlretrieve(audio_url, 'temp_files/'+itemid+".mp3")

        print 'Downloading and merging images...'

        urllib.urlretrieve(image, "temp_files/image.jpg")

        audio = AudioFileClip("temp_files/"+itemid+".mp3")

        imageTitle = ImageClip(channel+'/res/titlelayer.png')
        background = ImageClip('temp_files/image.jpg').set_audio(audio)

        # Merge background and logo
        video = CompositeVideoClip([background, imageTitle]) 

        # Save a frame for thumbnail

        # Export the video

        # Remove the mp3
        os.system('rm temp_files/'+itemid+'.mp3')

        # Finally upload the video and remove it from disk when over
        yt_command = """youtube-upload 
            --description=\""""+title+" by "+artist+"""\" 
            --category=Music --tags='chill, electro, music' 
            --playlist 'Discover new sounds' 
            --thumbnail 'temp_files/"""+itemid+""".jpg' 
            temp_files/"""+itemid+""".mp4 """

        os.system(yt_command + "&& rm temp_files/"+itemid+".mp4 &")

        hs = open(uploaded_location,"a")

        print colored("An error happened, next.", 'red')

Get all channels sub-folders

for channel in [d for d in os.listdir('.') if os.path.isdir(os.path.join('.', d))]:
if channel == "temp_files": continue;

for channel in [d for d in os.listdir('.') if os.path.isdir(os.path.join('.', d))]:

	if channel == "temp_files": 

    with open(channel+'/info.json') as data_file:    
        channelInfo = json.load(data_file)

    print '----------------------------------'
    print 'Treating channel '+colored(channelInfo['name'], 'blue')
    print '----------------------------------'

    for link in channelInfo['hypem']:

        # Parse tracks from the hypemachine links
        r = requests.get(link)
        tracks = json.loads(r.content)

        # For each tracks, create a video and upload it
        for track in tracks:

colored("Script over.", 'red')

I wrote the id of the music to a file uploaded.txt  located on my Dropbox, so I could use the script on different computers without worrying that a music would be uploaded multiple times.

Then, you can either choose to manually run the script once a day or set up a cron job to do it for ya.

What happened next

Unfortunately, after a while (6 months) YouTube disabled my channels after a copyright notice, without really explaining what video was the problem.

The first channel I published brought approximately 1000 subscribers and $1/day before it was shutdown, after a few months of posting video automatically.

I would have posted my stats here but I can't access the dashboard anymore.

I'd like to try and start another channel with royalty-free music, to be free of copyright problems and take it as far as possible.

Subscribe to get future posts. No spam ever.

twitter - github