Облачная функция Firebase [Ошибка: превышен предел памяти. Вызов функции был прерван.] При загрузке видео на YouTube - PullRequest
0 голосов
/ 13 ноября 2018

Я пытался загрузить видео на YouTube с помощью облачной функции Firebase.

Что мне нужно, это когда пользователь загружает видео в облачное хранилище Firebase, запускается событие functions.storage.object (). OnFinalize, и в этом случае я сохраняю файл во временном местоположении и загружаю файл на YouTube. из временного местоположения на YouTube, после загрузки я удаляю оба файла.

Он отлично подойдет для небольших файлов.

Но если я загружаю большой файл, функция завершается, показывая эту ошибку

Ошибка: превышен лимит памяти. Вызов функции был прерван.

Код для загрузки видео

   var requestData = {
        'params': {
        'part': 'snippet,status'
        },
        'properties': {
        'snippet.categoryId': '22',
        'snippet.defaultLanguage': '',
        'snippet.description': "docdata.shortDesc",
        'snippet.tags[]': '',
        'snippet.title': "docdata.title",
        'status.embeddable': '',
        'status.license': '',
        'status.privacyStatus': 'public',
        'status.publicStatsViewable': ''
        }, 'mediaFilename': tempLocalFile
    };

    insertVideo(tempLocalFile, oauth2Client, requestData);

вставить видео функцию

function insertVideo( file, oauth2Client, requestData) {
    return new Promise((resolve,reject)=>{
        google.options({ auth: oauth2Client });
        var parameters = removeEmptyParameters(requestData['params']);
        parameters['auth'] = oauth2Client;
        parameters['media'] = { body:  fs.createReadStream(requestData['mediaFilename'])};
        parameters['notifySubscribers'] = false;
        parameters['resource'] = createResource(requestData['properties']);

        console.log("INSERT >>> ");
        let req = google.youtube('v3').videos.insert(parameters,  (error, received)=> {
            if (error) {
                console.log("in error")
                console.log(error);
                try {
                    fs.unlinkSync(file);
                } catch (err) {
                    console.log(err);
                } finally{
                    // response.status(200).send({ error: error })
                }
                reject(error)
            } else {
                console.log("in else")
                console.log(received.data)
                fs.unlinkSync(file);
                resolve();
            }
        }); 
    })

}

код для создания временного локального файла

           bucket.file(filePath).createReadStream()
            .on('error', (err)=> {
                reject(err)
            })
            .on('response', (response)=> {
                console.log(response)
            })
            .on('end', ()=> {
                console.log("The file is fully downloaded");
                resolve();
            })
            .pipe(fs.createWriteStream(tempLocalFile));

Каждый файл для чтения и записи обрабатывается потоками, любая идея о том, почему возникает проблема с памятью

Ответы [ 2 ]

0 голосов
/ 11 марта 2019

Вы также можете использовать возобновляемую загрузку видео , выполнив следующие действия:

  1. Ваши функции, запускаемые GCS, запускаются, когда видео завершает загрузку.
  2. Функция запускает возобновляемый сеанс загрузки , вычисляет, какие разумные блоки следует загрузить, и вставляет определения блоков в pubsub с диапазоном для каждого блока и идентификатором сеанса
  3. Вы создаете новую функцию, запускаемую pubsub, с темой, которая получает это сообщение, загружает порцию из GCS, используя заголовок range (недокументированный в JSON API, но я уже сообщил об этом), и загружает чанк на Youtube

Я не пробовал, но это может даже позволить параллельную загрузку на Youtube из разных функций, загружая разные чанки (что значительно повысит производительность, хотя в документах предполагается, что чанки нужно загружать по порядку). Вы можете загрузить произвольный кусок из объекта GCS, так что сторона GCS не является проблемой для распараллеливания.

Если параллельная загрузка не разрешена, вы можете просто вставить новое сообщение pubsub, когда функция завершит загрузку своего фрагмента с последним загруженным байтом, так что порядок выполнения функций упорядочен (хотя он допускает параллельную загрузку различных видео).

Это немного сложнее, но позволяет загружать видео произвольного размера (до текущего ограничения в 128 ГБ на Youtube) из небольших функций.

Позаботьтесь о том, чтобы правильно обрабатывать сбои (возможно, повторно вставив блок в тему pubsub).

0 голосов
/ 13 ноября 2018

Единственная доступная для записи часть файловой системы в облачных функциях - это каталог /tmp. Согласно документации здесь :

Это локальная точка монтирования диска, известная как том "tmpfs", в котором Данные, записанные на томе, хранятся в памяти. Обратите внимание, что это будет использовать ресурсы памяти, выделенные для функции.

Вот почему вы достигли предела памяти большими файлами.

Ваши варианты:

  • Выделите больше памяти для вашей функции (в настоящее время до 2 ГБ)
  • Выполнить загрузку из среды, в которой вы можете записать в файловую систему. Например, ваша облачная функция может вызвать сервис App Engine Flexible для выполнения загрузки.
...