Создание видео из картинок и музыки на C#


Появилась задача. Необходимо создать программу для Windows, которая бы на вход принимала изображение и аудиофайл в формате mp3, а на выход выдавала видео в заданном разрешении – картинка, созданная из изображения и обложки в файле песни, а также музыка. Давайте её решим (напишем код).

Данную задачу вообще можно решить несколькими способами. Немного подумав, я выбрал самый, как мне кажется, простой – использовать FFMPeg, причем не как часть программы, а как отельный, внешний вызов приложения через командную строку.

Таким образом, план программы получается такой:

  1. Получение всех данных (адреса img и mp3, выходная папка), валидация их
  2. Извлечение обложки из песни
  3. Наложение обложки на шаблон изображения
  4. Вызов FFMpeg с параметрами для конвертации
Получение данных

Тут все просто – набрасываем на форму кнопки, прямо в них суем подобные конструкции

OpenFileDialog openFileDialog1 = new OpenFileDialog();
if (openFileDialog1.ShowDialog() == DialogResult.Cancel){
    return;
}
label1.Text = openFileDialog1.FileName;
Потом перед тем, как начать работу, проверяем, что в label-ах что-то есть и это что-то является корректным путем к файлу или папке.

Извлечение обложки из песни

TagLib.File f = new TagLib.Mpeg.AudioFile(audio);
if (f.Tag.Pictures.Length > 0){
	TagLib.IPicture pic = f.Tag.Pictures[0];
	MemoryStream ms = new MemoryStream(pic.Data.Data);
	if (ms != null && ms.Length > 4096){
		Image currentImage = Image.FromStream(ms);
		//тут дальше что хотим делаем с обложкой currentImage
	}
}
Наложение обложки на шаблон изображения

static Image AddWaterMark(Image orig, Image waterMark, Point location){           
	Image result = new Bitmap(orig);
	using (Graphics g = Graphics.FromImage(result))
	{
		g.DrawImage(waterMark, location);
	}
	return result;
}

Image templateImg = Image.FromFile(img);
Image endImage = AddWaterMark(templateImg, newCurrentImage, new Point(680, 0));
Bitmap image = new Bitmap(endImage);

//добавляем по краям белую полоску
if (image.Width > 50 && image.Height > 50){
	for (int i = xStart; i < xStart + shirinaWhite + 1; i++)
	{
		for (int j = 0; j < sizeAlbom; j++)
		{
			image.SetPixel(i, j, Color.White);
		}
	}

	for (int i = xStart; i < xStart + sizeAlbom + shirinaWhite; i++)
	{
		for (int j = sizeAlbom - 1; j < sizeAlbom + shirinaWhite; j++)
		{
			image.SetPixel(i, j, Color.White);
		}
	}

	for (int i = xStart + sizeAlbom - 1; i < xStart + sizeAlbom + shirinaWhite; i++)
	{
		for (int j = 0; j < sizeAlbom; j++)
		{
			image.SetPixel(i, j, Color.White);
		}
	}
	image.Save("endtest.jpg", ImageFormat.Jpeg);
}
Пауза

После этого пункта я рекомендую сделать небольшую паузу в программе. Почему? Дело в том, что хотя современные SSD диски и шустро пишут информацию, все же это происходит не мгновенно. И перед тем, как FFMpeg начнет считывать картинку себе, стоит дождаться пока картинка, полностью займет положенное место в файловой системе. Ну либо можно обработать ошибку чтения, но в нашей программе для домашнего использования на одной машине это уже чрезмерно.

System.Threading.Thread.Sleep(3000);
Непосредственно создание видео из mp3 и изображения в FFMpeg

Вызов FFMpeg с параметрами для конвертации

System.Diagnostics.ProcessStartInfo proc = new System.Diagnostics.ProcessStartInfo();
string command = pathFFMpeg + " -loop 1 -i \"endtest.jpg\" -i \"" + audio + "\" -shortest -s 3840x2160 \"" + outFile + "\" -y";
Console.WriteLine(command);
var process = System.Diagnostics.Process.Start("cmd.exe", @"/c " + command);
process.WaitForExit();
Параметры запуска FFMpeg можете прочитать в документации к этой программе. Здесь мы указываем расширение, адреса файлов, сразу перезапись без подтверждений (если уже есть с таким названием).

Итоги



Вот так просто можно написать программу на C# для создания видео из картинок и музыки. Конечно, здесь не все, это просто набросок. Вам также скорее всего необходимо будет реализовать обработку ошибок, добавить тесты, методы изменяющие размеры картинок (при этом учесть число точек на дюйм), организовать работу всего этого в другом потоке (проще всего через BackgroundWorker) и так далее. Но, надеюсь, моя заметка даст вам правильное направление. В любом случае за плату я вас с удовольствием проконсультирую, если возникнут вопросы по программированию на C#.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, си шарп, видео, изображения, mp3




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




C++: построчное чтение из файла с проверкой его существования
Создание видео из картинок и музыки на C#
C++: String в string и нахождение позиции символа