Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to track the % of the video transcoded #104

Open
poussy opened this issue Apr 15, 2019 · 3 comments
Open

Is it possible to track the % of the video transcoded #104

poussy opened this issue Apr 15, 2019 · 3 comments
Labels

Comments

@poussy
Copy link

poussy commented Apr 15, 2019

After uploading , the video is being transcoded , can we track the % .
How can we create the progress circle while transcoding seen at vimeo official website after upload?

@tommypenner
Copy link

@poussy Sorry, it's not yet possible to track a video's transcode progress.

@karlhorky
Copy link
Contributor

karlhorky commented Jul 31, 2023

Workaround (automatic upload from backend)

For an automatic upload from the backend (eg. when a user visits a page, without uploading a video of their own), what we do is recursively call the /videos/<video_id> API endpoint every 3 seconds and looking checking the .length of the files array returned (example TypeScript code uses @vimeo/[email protected] with the promises API):

import { Vimeo } from '@vimeo/vimeo';

const client = new Vimeo(
  config.VIMEO_CLIENT_ID,
  config.VIMEO_CLIENT_SECRET,
  config.VIMEO_ACCESS_TOKEN,
);

/**
 * Continually request a Vimeo uploaded video URI,
 * pausing for 3 seconds between each request
 * (transcoding can take a while and we don't want
 * to send too many API requests if we can avoid
 * it) until the files array contains greater
 * than 0 elements
 */
async function getFilesByUriRecursive(uri: string): Promise<
  (
    | {
        quality: 'sd';
        rendition: '240p' | '360p';
        type: 'video/mp4';
        width: number;
        height: number;
        link: string;
        created_time: string;
        fps: number;
        size: number;
        md5: string;
        public_name: '240p' | '360p';
      }
    | {
        quality: 'hd';
        rendition: '720p' | '1080p';
        type: 'video/mp4';
        width: number;
        height: number;
        link: string;
        created_time: string;
        fps: number;
        size: number;
        md5: string;
        public_name: '720p' | '1080p';
      }
    | {
        quality: 'hls';
        rendition: 'adaptive';
        type: 'video/mp4';
        width: number;
        height: number;
        link: string;
        created_time: string;
        fps: number;
        size: number;
        md5: string;
        public_name: '240p';
      }
  )[]
> {
  const response = await client.request(uri);

  if (!('files' in response.body)) {
    throw new Error('No files in response');
  }

  if (response.body.files.length < 1) {
    await new Promise((resolve) => { setTimeout(resolve, 3000); });
    return getFilesByUriRecursive(uri);
  }

  return response.body.files;
}

Example usage:

let uri: string;

try {
  uri = await client.upload(
    filePath,
    { name: 'example-video-name', folder_uri: '/folders/<folder_id>' },
    // Progress callback doesn't track transcoding progress, which takes most time
    () => {},
  );
} catch (error) {
  return {
    errors: [{ message: (error as Error).message }],
  };
}

const files = await getFilesByUriRecursive(uri);

@karlhorky
Copy link
Contributor

Workaround (active upload from user)

For a user upload from the frontend over our backend (eg. a user uploads a video of their own to our backend, and then our backend uploads to Vimeo), what we do is:

  1. Track the progress of the upload to our backend using onUploadProgress from axios and display a progress bar
    await axios.post(url, data, {
      onUploadProgress: (uploadEvent) => {
        // If event.lengthComputable is not true, fake a
        // progress update by showing a 1% increase as
        // long as the percentage is not above 98%
        if (!uploadEvent.total) {
          setProgressPercentage((percentage) => {
            if (percentage > 98) {
              return percentage;
            }
            return percentage + 1;
          });
          return;
        }
    
        setProgressPercentage(
          (uploadEvent.loaded / uploadEvent.total) * 100,
        );
      },
    });
  2. Recursively call Vimeo the /videos/<video_id> API endpoint using the ?fields=status parameter to check for a VimeoVideoStatus that is *not* 'transcode_starting' or 'transcoding'
  3. Fake the percentage of the progress bar to get to the end in about 5 minutes (stop at 98%), because there is no time estimate from Vimeo's API
    let percentage = 0;
    
    const transcodingProgressUpdateInterval = setInterval(() => {
      // Stop updating progress once it is at 98%
      // in case the transcoding has not yet completed
      if (percentage > 98) {
        clearInterval(transcodingProgressUpdateInterval);
        return percentage;
      }
      // Reach 100% in just over 5 minutes
      return percentage + 0.48;
    }, 1500);
    
    const transcodeStatusResponse =
      await getStatusByVideoIdRecursive(vimeoVideoId);
    
    clearInterval(transcodingProgressUpdateInterval);
    percentage = 100;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants