7

Issue

What I'm trying to do is simply convert and compress a video file from the storage bucket in node.js using @google-cloud/video-transcoder (TranscoderServiceClient v1). Single input file and a single output. The input file may or may not have an audio track. Everything works as expected when the file includes an audio track, but when it doesn't, I'll get an error with code 3:

\atom atom0 does not have any inputs (input0) with an audio track

Only options I can think of currently, are:

  1. Use pubsub to listen for job errors and run failed jobs again, but without the audio stream (got this working).
  2. Use something like ffprobe before starting the job to determine if there is an audio track in the file.

However, I would prefer not reading the file twice: once for determining available tracks and then for transcoding. And I wouldn't like to run the job twice. I found nothing in docs about how to only include the audio track if it exists (or replace it with an empty audio track if it does not exist).

Current config:

config: {
    elementaryStreams: [
        {
            key: 'video-stream0',
            videoStream: {...},
        },
        {
            key: 'audio-stream0',
            audioStream: {...},
        },
    ],
    muxStreams: [
        {
            key: 'hd',
            container: 'mp4',
            elementaryStreams: ['video-stream0', 'audio-stream0'],
        },
    ],
}

Documentation used:

  1. Setup - Transcoder API Node.js Client reference (my implementation is near identical with the ad-hoc example in googleapis git)
  2. Config - JobConfig
  3. Call options - CallOptions

Update

@Betjens suggested to use CallOptions to retry the job without pubsub, but I can't get it to work in node.js. The job does not retry, with or without backOffSettings. The official example for pubsub retry is an example for another API that uses CallOptions, but it does not seem to work in my case.

const callOptions = {
    retry: {
        retryCodes: [3],  // 'INVALID_ARGUMENT', error code if audio missing
        backoffSettings: {...}
    },
    retryRequestOptions: {
        request: requestWithoutAudio // request without audio streams to retry
    }
}

// Run request
const [response] = await transcoderServiceClient.createJob(request, callOptions);
Erich Loob
  • 101
  • 4
  • Hello, can you provide the documentation links for this? so we can be at the same page. Also where are you using your setup config? can you provide details to it. Also, as an addition I'm adding this official documentation [link](https://cloud.google.com/video-intelligence/docs/transcription#video_speech_transcription_gcs-nodejs) you can find some info about using transcripts library with node.js on google cloud shell. – Betjens Nov 08 '21 at 15:35
  • @Betjens Thank you, I added the links to docs I followed to the bottom of the post. My implementation is near identical with the official adhoc example in git: https://github.com/googleapis/nodejs-video-transcoder/blob/main/samples/createJobFromAdHoc.js . – Erich Loob Nov 08 '21 at 16:49
  • Also, I think there is some confusion. My issue is with @google-cloud/video-transcoder not @google-cloud/video-intelligence. I'm trying to transcode the video, not transcribe. And as an update I can say that running the failed job again without the audio track in config works. But it's clearly not an ideal solution. – Erich Loob Nov 09 '21 at 10:22
  • 1
    Based on the [official documentation](https://googleapis.dev/nodejs/transcoder/latest/v1beta1.TranscoderServiceClient.html#createJob), on create job there is a [retry](https://github.com/googleapis/nodejs-video-transcoder/blob/26c69a976cce29d180310b4c5f34c8d0134929a7/src/v1/transcoder_service_client.ts#L382) option parameter where you can pass a function, have you try implemented the logic for it? ( I did it on python, have not try on node.js ) – Betjens Nov 09 '21 at 14:56
  • Just to give an idea, you can use the handler to perform a default activity on fail processing videos. Also, take a look about this documentation about jobconfig audio defaults setup [here](https://cloud.google.com/transcoder/docs/concepts/stream-mappings). – Betjens Nov 09 '21 at 16:26
  • Can't get it to work. The docs I followed do not include the options: https://googleapis.dev/nodejs/transcoder/latest/google.cloud.video.transcoder.v1.TranscoderService.html#createJob2 . I tried however with the following options as in the google-gax docs you provided: { retry: { retryCodes: [3] }, maxRetries: 1, retryRequestOptions: { retries: 1, request: request_wo_audio } }, but no luck. It does not run again. Not sure how to configure the options to be honest. The pubsub method currently works, but your method would be better. I'll try to play around with it. – Erich Loob Nov 10 '21 at 14:59
  • And I have gone through the stream mappings docs already, but did not find an answer. So best bet right now would be the retry options or simply keep using the pubsub to run jobs again. – Erich Loob Nov 10 '21 at 15:01
  • Just noticed that the docs you provided (that include the retry options) are for v1beta1, but I'm using v1. I'll look into the beta and specify this in the original post. – Erich Loob Nov 10 '21 at 15:05
  • I'm sry this is the correct [link](https://googleapis.dev/nodejs/transcoder/latest/v1.TranscoderServiceClient.html#createJob) – Betjens Nov 10 '21 at 15:26
  • By the way, on you test configuration you are using 'video-stream1', 'audio-stream0' which in you main config set you are only setting 'video-stream0' and 'audio-stream0'... – Betjens Nov 11 '21 at 10:15
  • Thanks for pointing out the typo. I fixed it in the original post, but it's not related to the issue itself (just a typo I made when posting the question). I'm still trying to figure out how to use the CallOptions in node.js, thus far no success. – Erich Loob Nov 12 '21 at 11:16

1 Answers1

2

I will post this to recap what I have found of your case. And the suggest the actions based on the comment exchange.

Configuration tips:

  • Make sure your configuration elementaryStreams keys match the muxStreams elementaryStreams match else you may have issues with the transcoder service.

In you configuration you are making reference of 'video-stream1'

muxStreams: [
        {
            key: 'hd',
            container: 'mp4',
            elementaryStreams: ['video-stream1', 'audio-stream0'],
        },
    ],

which do not exist in your elementaryStreams

elementaryStreams: [
        {
            key: 'video-stream0',
            videoStream: {...},
        },
        {
            key: 'audio-stream0',
            audioStream: {...},
        },
    ],

Retry tips:

  • Client for Node.js I have not see this kind of implementation as described on transcoderserviceclient.
  • Client for Python, there is an option to set a retry operation when you create a job which you can use to pass a retry [google.api.retry] on the client.

Python Sample (from Google API Retry)

@retry.Retry(predicate=if_exception_type(exceptions.NotFound))
def check_if_exists():
    return client.does_thing_exist()

is_available = check_if_exists()

** update 05/09: I have refreshed my answer with the latest updates.

retries helpful links:

Summarize:

  • You can use the client retry and pass a google retry to perform the retry operation with the exception you want to handle.
Betjens
  • 1,353
  • 2
  • 4
  • 13
  • @WytrzymałyWiktor No, not exactly. I'm still having issues with CallOptions in node.js. Updated original question. But thank you Betjens, if I manage to figure out the node.js implementation, I'll share the code in comments and accept the answer. – Erich Loob Nov 12 '21 at 11:38
  • Hello @ErichLoob, have you try using the configureRetries sample for NodeJs. Here is the [link](https://github.com/googleapis/nodejs-storage/blob/main/samples/configureRetries.js). Let me know if you were able to get that sample working on your side. – Betjens Nov 13 '21 at 11:43
  • Also, as pointed in the summarize, the appropriate approach is just to reprocess trough the fails ones leaving aside retries as that should keep its original behavior (check the link [configuring retries](https://googleapis.dev/python/storage/latest/retry_timeout.html)). It may work as a workaround but we may encounter issues later on as the operation retry_policy is timed by default and only catch certain errors. – Betjens Nov 15 '21 at 08:54
  • This should be a lot easier. Any chance somebody at the cloud platform team takes this one? – reco May 07 '22 at 18:08