Перед началом работы вы, возможно, захотите посмотреть пример приложения
которое мы создали для наложения слоев видео для создания эффекта «картинка в картинке».
Функция «картинка в картинке» стала довольно распространенной в медиасфере, и теперь она доступна в браузерах.
браузерах для просмотра видео при прокрутке веб-страницы, а также в качестве вставки во многих видео на YouTube для
создатели могут давать комментарии к своим видео.
Это руководство поможет вам создать простое приложение, которое можно использовать для добавления функции «картинка в картинке» в ваши видео.
к вашим видео. В этом руководстве мы используем Node.js.
Обратите внимание, что в более новой статье рассматривается создание PiP-видео с помощью динамических видеошаблонов.
Prequesites
Node.js
Наш скрипт будет написан на Node.js, и мы сделаем его максимально простым, с минимальными
зависимостей.
Аккаунт разработчика Shotstack
API Shotstack позволяет вам рендерить десятки тысяч видео в облаке и персонализировать каждое отдельное видео с помощью SDK Node.js. API способен одновременно рендерить сотни видео в облаке, и вы можете автоматизировать генерацию сотен похожих видео. После регистрации просто войдите в систему, чтобы получить ключ API.
Настройка сцены
Мы собираемся создать видеоролик для YouTube, в котором будут обсуждаться мои 5 самых любимых игр для OSX. У нас есть
куча медиаактивов, таких как игровые кадры и видеокомментарии с различным соотношением сторон, разрешением и типом файлов.
которые мы соберем в композитное видео.
JSON
Видеомонтаж Shotstack — это просто JSON-файл, состоящий из временной шкалы, клипов, переходов и эффектов, который отправляется в API, который берет на себя рендеринг.
API, который берет на себя процесс рендеринга, создавая видеофайл mp4.
В приведенном ниже JSON мы разместили часть игровых кадров в серии, а внизу поместили наш масштабированный видеокомментарий.
левой части этих видео.
{
"timeline": {
"background": "#000000",
"tracks": [
{
"clips": [
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/deponia_pip.mov"
},
"start": 0,
"length": 10,
"scale": 0.2,
"position": "bottomRight",
"offset": {
"x": -0.05,
"y": 0.1
}
},
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/hacknet_pip.mov"
},
"start": 10,
"length": 10,
"scale": 0.2,
"position": "bottomRight",
"offset": {
"x": -0.05,
"y": 0.1
}
},
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/beholder_pip.mov"
},
"start": 20,
"length": 10,
"scale": 0.2,
"position": "bottomRight",
"offset": {
"x": -0.05,
"y": 0.1
}
},
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/pinstripe_pip.mov"
},
"start": 30,
"length": 10,
"scale": 0.2,
"position": "bottomRight",
"offset": {
"x": -0.05,
"y": 0.1
}
},
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/thimbleweed_pip.mov"
},
"start": 40,
"length": 10,
"scale": 0.2,
"position": "bottomRight",
"offset": {
"x": -0.05,
"y": 0.1
}
}
]
},
{
"clips": [
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/deponia.mkv",
"volume": 0.1,
"trim": 10
},
"start": 0,
"length": 10
},
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/hacknet.mkv",
"volume": 0.1,
"trim": 10
},
"start": 10,
"length": 10
},
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/beholder.mkv",
"volume": 0.1,
"trim": 10
},
"start": 20,
"length": 10
},
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/pinstripe.mkv",
"volume": 0.1,
"trim": 40
},
"start": 30,
"length": 10
},
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/thimbleweed.mkv",
"volume": 0.1,
"trim": 10
},
"start": 40,
"length": 10
}
]
}
]
},
"output": {
"format": "mp4",
"resolution": "sd"
}
}
Вы можете отправить эту полезную нагрузку JSON непосредственно в API с помощью Curl или Postman, но для данного руководства мы сохраним ее в файле под названием
JSON в файле template.json
и прочитаем его с помощью нашего скрипта Node.js.
Приложение Node.js
Создайте новый файл скрипта Node.js и добавьте приведенный ниже код. Сценарий прочитает файл шаблона JSON, отправит его на сайт
API render
endpoint и затем опрашивать API для получения статуса рендеринга. Для рендеринга потребуется около 30 секунд
и в консоль будет выведен URL, который вы можете загрузить и просмотреть. Вам потребуется установить dotenv
и axios
узловые модули перед запуском скрипта.
require('dotenv').config();
const axios = require('axios');
const shotstackUrl = 'https://api.shotstack.io/stage/';
const shotstackApiKey = process.env.SHOTSTACK_API_KEY; // Either declare your API key in your .env file, or set this variable with your API key right here.
const json = require('./template.json');
/**
* Post the JSON video edit to the Shotstack API
*
* @param {String} json The JSON edit read from template.json
*/
const renderVideo = async (json) => {
const response = await axios({
method: 'post',
url: shotstackUrl + 'render',
headers: {
'x-api-key': shotstackApiKey,
'content-type': 'application/json'
},
data: json
});
return response.data;
}
/**
* Get the status of the render task from the Shotstack API
*
* @param {String} uuid The render id of the current video render task
*/
const pollVideoStatus = async (uuid) => {
const response = await axios({
method: 'get',
url: shotstackUrl + 'render/' + uuid,
headers: {
'x-api-key': shotstackApiKey,
'content-type': 'application/json'
},
});
if (!(response.data.response.status === 'done' || response.data.response.status === 'failed')) {
setTimeout(() => {
console.log(response.data.response.status + '...');
pollVideoStatus(uuid);
}, 3000);
} else if (response.data.response.status === 'failed') {
console.error('Failed with the following error: ' + response.data.response.error);
} else {
console.log('Succeeded: ' + response.data.response.url);
}
}
// Run the script
(async () => {
try {
const render = await renderVideo(JSON.stringify(json));
pollVideoStatus(render.response.id);
} catch (err) {
console.error(err);
}
})();
Первоначальный результат
Наш первый проект будет выглядеть так, как показано на видео ниже:
Довольно просто! Мы можем добавить некоторые улучшения, чтобы было понятнее, о чем видео, и оно еще не
пока не похоже на листик. Различные клипы не очень красиво переходят друг в друга, и в целом нет никакого контекста
что происходит за пределами комментария.
Последние штрихи
В JSON ниже добавлена пара HTML-активов. Эти активы используют HTML и CSS для создания базовой анимации, которая обеспечивает
контекст обсуждаемой игры. Мы также добавим несколько переходов к игровым кадрам, чтобы более органично
перехода от одного элемента к другому и включим начальную заглавную сцену, которая дает понять, о чем видео.
{
"timeline": {
"background": "#000000",
"tracks": [
{
"clips": [
{
"asset": {
"type": "title",
"text": "Top 5 Steam games on OSX",
"style": "blockbuster",
"color": "#ffffff",
"size": "large",
"background": "#000000",
"position": "center"
},
"start": 0,
"length": 3,
"transition":{
"in": "fade",
"out": "fade"
}
}
]
},
{
"clips": [
{
"asset": {
"type": "html",
"html": "<div>5</div>",
"css": "div {font-family: "Lato";font-size: 90px; font-weight: bold; padding: 5%;}",
"width": 150,
"height": 150,
"background": "#ecf0f1",
"position": "center"
},
"transition": {
"in": "slideRight",
"out": "slideLeft"
},
"start": 3,
"length": 4,
"position": "bottomLeft",
"offset":{
"x": 0.05,
"y": 0.15
}
},
{
"asset": {
"type": "html",
"html": "<div>Daedalic Entertainment, 2012</div>",
"css": "div {font-family: "Lato";font-size: 18px; font-weight: bold; padding: 5%;}",
"width": 300,
"height": 50,
"background": "#ecf0f1",
"position": "center"
},
"transition": {
"in": "slideUp",
"out": "slideDown"
},
"start": 3,
"length": 4,
"position": "bottomLeft",
"offset":{
"x": 0.18,
"y": 0.15
}
},
{
"asset": {
"type": "html",
"html": "<div>Deponia</div>",
"css": "div {font-family: "Lato";font-size: 60px; font-weight: bold; padding: 5%;}",
"width": 400,
"height": 100,
"background": "#bdc3c7",
"position": "center"
},
"transition": {
"in": "slideDown",
"out": "slideUp"
},
"start": 3,
"length": 4,
"position": "bottomLeft",
"offset":{
"x": 0.18,
"y": 0.219
}
},
{
"asset": {
"type": "html",
"html": "<div>4</div>",
"css": "div {font-family: "Lato";font-size: 90px; font-weight: bold; padding: 5%;}",
"width": 150,
"height": 150,
"background": "#ecf0f1",
"position": "center"
},
"transition": {
"in": "slideRight",
"out": "slideLeft"
},
"start": 11,
"length": 5,
"position": "bottomLeft",
"offset":{
"x": 0.05,
"y": 0.15
}
},
{
"asset": {
"type": "html",
"html": "<div>Fractal Alligator, 2015</div>",
"css": "div {font-family: "Lato";font-size: 18px; font-weight: bold; padding: 5%;}",
"width": 300,
"height": 50,
"background": "#ecf0f1",
"position": "center"
},
"transition": {
"in": "slideUp",
"out": "slideDown"
},
"start": 11,
"length": 5,
"position": "bottomLeft",
"offset":{
"x": 0.18,
"y": 0.15
}
},
{
"asset": {
"type": "html",
"html": "<div>Hacknet</div>",
"css": "div {font-family: "Lato";font-size: 60px; font-weight: bold; padding: 5%;}",
"width": 400,
"height": 100,
"background": "#bdc3c7",
"position": "center"
},
"transition": {
"in": "slideDown",
"out": "slideUp"
},
"start": 11,
"length": 5,
"position": "bottomLeft",
"offset":{
"x": 0.18,
"y": 0.219
}
},
{
"asset": {
"type": "html",
"html": "<div>3</div>",
"css": "div {font-family: "Lato";font-size: 90px; font-weight: bold; padding: 5%;}",
"width": 150,
"height": 150,
"background": "#ecf0f1",
"position": "center"
},
"transition": {
"in": "slideRight",
"out": "slideLeft"
},
"start": 21,
"length": 5,
"position": "bottomLeft",
"offset":{
"x": 0.05,
"y": 0.15
}
},
{
"asset": {
"type": "html",
"html": "<div>Warm Lamp Games, 2016</div>",
"css": "div {font-family: "Lato";font-size: 18px; font-weight: bold; padding: 5%;}",
"width": 300,
"height": 50,
"background": "#ecf0f1",
"position": "center"
},
"transition": {
"in": "slideUp",
"out": "slideDown"
},
"start": 21,
"length": 5,
"position": "bottomLeft",
"offset":{
"x": 0.18,
"y": 0.15
}
},
{
"asset": {
"type": "html",
"html": "<div>Beholder</div>",
"css": "div {font-family: "Lato";font-size: 60px; font-weight: bold; padding: 5%;}",
"width": 400,
"height": 100,
"background": "#bdc3c7",
"position": "center"
},
"transition": {
"in": "slideDown",
"out": "slideUp"
},
"start": 21,
"length": 5,
"position": "bottomLeft",
"offset":{
"x": 0.18,
"y": 0.219
}
},
{
"asset": {
"type": "html",
"html": "<div>2</div>",
"css": "div {font-family: "Lato";font-size: 90px; font-weight: bold; padding: 5%;}",
"width": 150,
"height": 150,
"background": "#ecf0f1",
"position": "center"
},
"transition": {
"in": "slideRight",
"out": "slideLeft"
},
"start": 31,
"length": 5,
"position": "bottomLeft",
"offset":{
"x": 0.05,
"y": 0.15
}
},
{
"asset": {
"type": "html",
"html": "<div>Atmos Games, 2017</div>",
"css": "div {font-family: "Lato";font-size: 18px; font-weight: bold; padding: 5%;}",
"width": 300,
"height": 50,
"background": "#ecf0f1",
"position": "center"
},
"transition": {
"in": "slideUp",
"out": "slideDown"
},
"start": 31,
"length": 5,
"position": "bottomLeft",
"offset":{
"x": 0.18,
"y": 0.15
}
},
{
"asset": {
"type": "html",
"html": "<div>Pinstripe</div>",
"css": "div {font-family: "Lato";font-size: 60px; font-weight: bold; padding: 5%;}",
"width": 400,
"height": 100,
"background": "#bdc3c7",
"position": "center"
},
"transition": {
"in": "slideDown",
"out": "slideUp"
},
"start": 31,
"length": 5,
"position": "bottomLeft",
"offset":{
"x": 0.18,
"y": 0.219
}
},
{
"asset": {
"type": "html",
"html": "<div>1</div>",
"css": "div {font-family: "Lato";font-size: 90px; font-weight: bold; padding: 5%;}",
"width": 150,
"height": 150,
"background": "#ecf0f1",
"position": "center"
},
"transition": {
"in": "slideRight",
"out": "slideLeft"
},
"start": 41,
"length": 5,
"position": "bottomLeft",
"offset":{
"x": 0.05,
"y": 0.15
}
},
{
"asset": {
"type": "html",
"html": "<div>Terrible Toybox, 2017</div>",
"css": "div {font-family: "Lato";font-size: 18px; font-weight: bold; padding: 5%;}",
"width": 300,
"height": 50,
"background": "#ecf0f1",
"position": "center"
},
"transition": {
"in": "slideUp",
"out": "slideDown"
},
"start": 41,
"length": 5,
"position": "bottomLeft",
"offset":{
"x": 0.18,
"y": 0.15
}
},
{
"asset": {
"type": "html",
"html": "<div>Thimbleweed Park</div>",
"css": "div {font-family: "Lato";font-size: 40px; font-weight: bold; padding: 5%;}",
"width": 400,
"height": 100,
"background": "#bdc3c7",
"position": "center"
},
"transition": {
"in": "slideDown",
"out": "slideUp"
},
"start": 41,
"length": 5,
"position": "bottomLeft",
"offset":{
"x": 0.18,
"y": 0.219
}
}
]
},
{
"clips": [
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/deponia_pip.mov"
},
"start": 3,
"length": 7,
"scale": 0.2,
"position": "bottomRight",
"offset": {
"x": -0.05,
"y": 0.1
}
},
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/hacknet_pip.mov"
},
"start": 10,
"length": 10,
"scale": 0.2,
"position": "bottomRight",
"offset": {
"x": -0.05,
"y": 0.1
}
},
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/beholder_pip.mov"
},
"start": 20,
"length": 10,
"scale": 0.2,
"position": "bottomRight",
"offset": {
"x": -0.05,
"y": 0.1
}
},
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/pinstripe_pip.mov"
},
"start": 30,
"length": 10,
"scale": 0.2,
"position": "bottomRight",
"offset": {
"x": -0.05,
"y": 0.1
}
},
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/thimbleweed_pip.mov"
},
"start": 40,
"length": 10,
"scale": 0.2,
"position": "bottomRight",
"offset": {
"x": -0.05,
"y": 0.1
},
"transition":{
"out": "fade"
}
}
]
},
{
"clips": [
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/deponia.mkv",
"volume": 0.1,
"trim": 10
},
"start": 3,
"length": 7,
"transition":{
"in": "fade",
"out": "fade"
}
},
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/hacknet.mkv",
"volume": 0.1,
"trim": 10
},
"start": 10,
"length": 10,
"transition":{
"in": "fade",
"out": "fade"
}
},
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/beholder.mkv",
"volume": 0.1,
"trim": 10
},
"start": 20,
"length": 10,
"transition":{
"in": "fade",
"out": "fade"
}
},
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/pinstripe.mkv",
"volume": 0.1,
"trim": 40
},
"start": 30,
"length": 10,
"transition":{
"in": "fade",
"out": "fade"
}
},
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/pip/thimbleweed.mkv",
"volume": 0.1,
"trim": 10
},
"start": 40,
"length": 10,
"transition":{
"in": "fade",
"out": "fade"
}
}
]
}
],
"fonts": [
{
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/fonts/Lato-Bold.ttf"
}
]
},
"output": {
"format": "mp4",
"resolution": "sd"
}
}
Окончательный результат
Конечный результат — профессионально отредактированное видео со списком статей и видеокомментарием «картинка в картинке». PewDiePie
мог бы позавидовать.
Заключение
Это руководство показывает, как создать приложение, которое помещает масштабированное видео поверх другого видео, создавая эффект «картинка в картинке».
эффект «картинка в картинке». Мы также использовали тип актива HTML и встроенные переходы слайдов для добавления анимированных нижних
третьи титры.
Чтобы продемонстрировать, как можно использовать приемы, описанные в этом руководстве, мы создали собственный
генератор «картинка в картинке» с открытым исходным кодом, который вы можете использовать для создания
видео «картинка в картинке». Полный исходный код доступен
на GitHub, который вы можете использовать в качестве отправной точки для создания собственного приложения.
Следите за Shotstack, чтобы узнать о программируемых видео и видеоприложениях. Начните с наших обучающих ресурсов, чтобы научиться создавать программируемые видео. Зарегистрируйтесь бесплатно, чтобы начать создавать потрясающие видеоприложения.