Adrián Varga
Adrián Varga

Reputation: 101

Transcoder API not working via Firebase Cloud Functions

I use Firebase in my Unity App. User's can upload videos to Firebase Storage (it's working good) and then I make trigger in Firebase Cloud Functions to transcode video (via Google Cloud Platform Transcoder API). This is not work, and I don't know why.

Google Cloud console cloud functions error: "Error: 3 INVALID_ARGUMENT: Invalid resource field value in the request."

Here is my code:

  const functions = require("firebase-functions");
    const admin = require("firebase-admin");
    admin.initializeApp();
    
    const db = admin.firestore();
    const { TranscoderServiceClient } = require('@google-cloud/video-transcoder');
    const { Storage } = require('@google-cloud/storage');
    const storage = new Storage();
    
//other functions..
//

    exports.transcodeVideo = functions.storage.object().onFinalize(async (object) => {
      try {
        const fileBucket = object.bucket;
        const filePath = object.name;
        const videoPath = `gs://${fileBucket}/${filePath}`;
    
        // Only if in videos/..
        if (!filePath.startsWith('videos/')) {
          console.log('Nem történt videó feltöltés az videos/ könyvtárba. A Cloud Function nem fut le.');
          return null;
        }
    
        console.log(`1. Transcode folyamat elindítva a videóhoz: ${videoPath}`);
    //videoPath is good!
    
        // A Google Cloud Transcoder API kliens inicializálása
        const transcoderClient = new TranscoderServiceClient();
    
        // Az új transcode elrendezés konfigurálása
        const jobTemplate = {
          jobConfig: {
            inputUri: videoPath,
            outputUri: 'gs://MY_APP.appspot.com/output/optimised.mp4', // THIS IS ONLY TEST NAME. MY_APP is my app.
            elementaryStreams: [
              {
                key: 'video_stream',
                videoStream: {
                  codec: 'h264',
                  heightPixels: 360, // Válaszd meg a kívánt alacsony SD felbontást
                  widthPixels: 640, // Válaszd meg a kívánt alacsony SD felbontást
                  bitrateBps: 1000000 // Válaszd meg a kívánt alacsony SD bitrátát
                }
              }
            ],
            muxStreams: [
              {
                key: 'sd_mux_stream',
                container: 'mp4'
              }
            ]
          }
        };
    
        console.log(`start transcode`); //After this get error in my console
        
        // Az új transcode elrendezés létrehozása és futtatása
        const [response] = await transcoderClient.createJob({
          job: jobTemplate
        });
    
        console.log(`Transcode folyamat elindítva a videóhoz: ${videoPath}`);
        //I don't see this in console, error before this.
    
        // A nem optimalizált videó törlése
        await storage.bucket(fileBucket).file(filePath).delete();
        console.log(`Nem optimalizált videó törölve: ${videoPath}`);
      } catch (error) {
        console.error('Hiba történt a transcode folyamat során:', error);
      }
    });

I don't know what is the problem.. Other functions work good. Cloud storage have service-account permission. I use "firebase deploy" command because my project base in firebase. I see in stack overflow maybe need other permission for "gcloud deploy...", but I use firebase. Maybe need to install gcloud too? Firebase storage = cloud storage, I think it is need work, but I don't know why get always this error.

Please help. Thanks, Adrian

Upvotes: 0

Views: 192

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83163

I'm not versed in Google Cloud Transponder but looking at the Transcoder API Documentation and at an official sample you need to pass to the createJob() method an object having these two properties:

{
  parent,
  job,
}

parent is a string representing the parent location to create and process the job (Format: projects/{project}/locations/{location}). It is unclear to me if it is required or not, the sample and the doc are not aligned on this aspect.

job is a compounded Object of type IJobTemplate with the following properties: name, config and labels. In turn, config is a compounded Object of type IJobConfig.

So you need to do something along the following lines (untested):

const request = {
      parent: "....",
      job: {
        name: "...",
        config: {
            inputUri: videoPath,
            outputUri: 'gs://MY_APP.appspot.com/output/optimised.mp4',
            ...
        }
      }
   };

// ...

const [response] = await transcoderClient.createJob(request);
// ...

(Hoping it helps you as this answer is strictly based on the documentation)

Upvotes: 0

Related Questions