How I fully automated the creation and posting of videos and news to youtube and twitter

I like to automate things and am happy when I don’t have to deal with them afterwards. It was the same with Youtube and Twitter. Filmmusic is a non-profit project, there are no employees and accordingly must be automated what can be automated.

In TYPO3 I set up a planner that generates a video every 4 hours.

Get a new song from database

I programmed a repository function, which gives me a new piece of music based on certain rules, which should serve as a basis.

/** @var Music $music */
$music = $this->musicRepository->getForYoutubePublish();

Generate a background image

With the Imagick functions I create a background image for the video based on the cover image and a CD case.

// Lade Hintergrund
// Bild erstellen
$im = new \Imagick();
$im->newImage(1920, 1080, new \ImagickPixel('white'));
$im->setImageFormat('jpg');

$imgBg = new \Imagick($imgPath);
$imgBg->setImageFormat('jpg');
$imgBg->resizeImage(1920, 1920, \Imagick::FILTER_LANCZOS, 1);
$imgBg->blurImage(20, 20);
$imgBg->setImageOpacity(0.7);

$im->compositeImage($imgBg, \Imagick::COMPOSITE_DEFAULT, 0, -420);

// lade Jwelcase
$imgFg = new \Imagick($this->pathJewelcase);
$imgFg->setImageFormat('png');

$im->compositeImage($imgFg, \Imagick::COMPOSITE_DEFAULT, 0, 0);

// Lade Vordergrund
$fgsize = 582;
$imgFg = new \Imagick($imgPath);
$imgFg->setImageFormat('png');
$imgFg->resizeImage($fgsize, $fgsize, \Imagick::FILTER_LANCZOS, 1);

$im->compositeImage($imgFg, \Imagick::COMPOSITE_DEFAULT, 136, 250);

file_put_contents($targetPathBackImage, $im);

Generate the video

Now I create a video with integrated audio visualization based on the just created background-image and the MP3 file, by using FFMPEG:

// Generate Video
$command = 'ffmpeg -y -loglevel error -i "' . $mp3Path . '" -loop 1 -i "' . $targetPathBackImage . '" -filter_complex "[0:a]showwaves=s=1060x700:mode=cline:colors=White,format=yuva420p[v];[1:v][v]overlay=805:190[outv]" -map "[outv]" -pix_fmt yuv420p -map 0:a -c:v libx264 -c:a copy -b:a 192k -shortest "' . $targetPathVideo . '" &>/dev/null';
exec($command);

Upload the video to youtube

Now I upload the video directly to Youtube using the PHP Google client:

$client = new \Google_Client();

// Filmmusic Youtube
$client->setClientId('xxx');
$client->setClientSecret('xxx');
$access_token = $client->refreshToken('xxx');

$access_token = $access_token['access_token'];
$client->setAccessToken($access_token);

// Create a snippet with title, description, tags and category ID
// Create an asset resource and set its snippet metadata and type.
// This example sets the video's title, description, keyword tags, and
// video category.
$snippet = new \Google_Service_YouTube_VideoSnippet();
$snippet->setTitle($title);
$snippet->setDescription($description);
$snippet->setTags($tags);

// Define an object that will be used to make all API requests.
$youtube = new \Google_Service_YouTube($client);

// Numeric video category. See
// https://developers.google.com/youtube/v3/docs/videoCategories/list
$snippet->setCategoryId($categoryId);

// Set the video's status to "public". Valid statuses are "public",
// "private" and "unlisted".
$status = new \Google_Service_YouTube_VideoStatus();
$status->privacyStatus = 'public';

// Associate the snippet and status objects with a new video resource.
$video = new \Google_Service_YouTube_Video();
$video->setSnippet($snippet);
$video->setStatus($status);

// Specify the size of each chunk of data, in bytes. Set a higher value for
// reliable connection as fewer chunks lead to faster uploads. Set a lower
// value for better recovery on less reliable connections.
$chunkSizeBytes = 1 * 1024 * 1024;

// Setting the defer flag to true tells the client to return a request which can be called
// with ->execute(); instead of making the API call immediately.
$client->setDefer(true);

// Create a request for the API's videos.insert method to create and upload the video.
$insertRequest = $youtube->videos->insert("status,snippet", $video);

// Create a MediaFileUpload object for resumable uploads.
$media = new \Google_Http_MediaFileUpload(
    $client,
    $insertRequest,
    'video/*',
    null,
    true,
    $chunkSizeBytes
);
$media->setFileSize(filesize($videoPath));


// Read the media file and upload it chunk by chunk.
$status = false;
$handle = fopen($videoPath, "rb");
while (!$status && !feof($handle)) {
    $chunk = fread($handle, $chunkSizeBytes);
    $status = $media->nextChunk($chunk);
}
fclose($handle);

// If you want to make other calls after the file upload, set setDefer back to false
$client->setDefer(false);

Post new video upoads and news to Twitter

With the help of “Zapier” I created two Zaps, which automatically post new videos from Youtube on Twitter, as well as new news from my blog. The basis for the news is the Filmmusic RSS feed.

Now what?

After watching everything for a few weeks, I don’t watch Youtube or Twitter anymore. Everything runs completely automatically and I don’t have to worry about anything anymore. So I can deal with the more important things again 🙂

That’s also the reason why I don’t answer any more comments, I just don’t notice it.

Be the first to comment

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.