preface

The happiness that can reflect human dignity is the greatest happiness, because it is related to human dignity. There is a lot of happiness that is reduced to human dignity. And the more can reflect the human dignity of happiness, the more a highest level of happiness, we read on the road, in fact, is to hope that we can continue. The pleasure of what? Superior happiness. —- Luo Xiang teacher’s classic sayings

start

Today, I saw an open source library for downloading Youtube videos using Node.js, and I was immediately impressed. I immediately opened the page and read the introduction. Good boy, it is so easy to use, and it will be much easier for workers to watch offline videos when they are commuting. Let’s take a look at the API github.com/fent/node-y…

This API is really neat. We just install the package locally and download it. It must not be that simple, the Internet is not working, haha. It doesn’t matter ~ I have cloud, I have Serverless, I don’t need, just play. No, no, no. I do.

My idea here is to generate a URL through the API gateway, and then transfer to the cloud function. The cloud function downloads the video to a temporary folder, and the cloud function uploads the video file to COS using the key of the running role. Then we can watch the video on the mobile phone through the COS client. To deploy the function to Hong Kong territory, there is no network restrictions, said I was excited.

So the idea is that this is the picture. Let’s do this then. Here I choose Tencent Cloud as the cloud provider, because Tencent Cloud has always had free quota can be used, our little amount of computation, basically do not need meters. Technically, we use Node.js, but of course we have to use TypeScript to make it compelling. We create an SCF function using the Serverless framework and then write code based on it.

$ npm i serverless -g
$ serverless init scf-demo
Copy the code

This project is created. Let’s go to SRC /index.js and write the file, first change the suffix to.ts, and then configure

$ npm i ytdl-core cos-nodejs-sdk-v5 -S
$ npm i typescript ts-node prettier -D
Copy the code

Where yTDL-core is the package for downloading videos, cos-nodejs-SDK-v5 is the Node SDK for uploading videos to COS

Then we need a powerful packaging tool to package all the code together, since the cloud function does not support running TS. Here I recommend NCC, a good packaging tool with zero configuration, built-in TS, on-demand loading, and support for all node packages

$ ncc build input.js -o dist
Copy the code

As you can see, the packaging method is very simple, and then we’ll configure this script into the NPM build command and that’s not nice. Let’s install it globally

$ npm i -g @vercel/ncc
Copy the code

coding

Let’s write some code:

const fs = require('fs')
const path = require('path')
const ytdl = require('ytdl-core')
const COS = require('cos-nodejs-sdk-v5')

exports.main_handler = (event, context, callback) = > {
  ytdl('https://www.youtube.com/watch?v=aqz-KE-bpKQ', {
    // For the sake of the demonstration, I only download a short clip, so I don't waste your traffic
    range: {
      start: 0.end: 5355705,
    },
  })
    .pipe(fs.createWriteStream(path.join('/tmp'.'video.mp4')))
    .on('finish'.() = > {
      // The temporary key must be filled with the SESSION TOKEN. Otherwise, it will not be uploaded
      // Obtain the temporary key by running the role
      const environment = JSON.parse(context.environment)
      const cos = new COS({
        SecretId: environment.TENCENTCLOUD_SECRETID,
        SecretKey: environment.TENCENTCLOUD_SECRETKEY,
        SecurityToken: environment.TENCENTCLOUD_SESSIONTOKEN,
      })

      cos.putObject(
        {
          Bucket: 'youtube-1253555942' /* We created COS Bucket */.Region: 'ap-hongkong' / * * /.Key: `video-The ${Date.now()}.mp4` /* File name */.StorageClass: 'STANDARD' /* Default is fine */.Body: fs.createReadStream(path.join('/tmp'.'video.mp4')), // Upload the file object
          onProgress: function (progressData) {
            console.log(JSON.stringify(progressData))
          },
        },
        function (err, data) {
          console.log(err || data)
          callback(null.'ok')
        },
      )
    })
    .on('error'.(e) = > {
      console.log(e)
    })
}

Copy the code

Import the package, enter the main function main_handler, write the download logic, save the temporary file, create the COS object, upload the COS file, end. All at once, very smooth. The type of TS is up to you. Cloud functions support two asynchronous methods: async and callback. In this case, we use streams so the callback method is simpler. Calling callback tells the engine that the function has completed. Let’s configure the project a little more and get it up and running. First, serverless. Yml, which is the configuration to upload to the cloud function, is used here in Hong Kong, and the code path is filled in our packaged directory, which can upload fewer files, so that the deployment speed is faster, other configurations are basically unchanged.

# Application information
app: scf-demo-3723d4bb

# Component information
component: scf # (required) The name of the reference component, currently using the Tencent SCF component
name: youtube # (required) Create instance name, please change to your instance name

# Component parameters
inputs:
  name: ${name}-${stage} # Function name
  src: ./dist  # Code path
  handler: index.main_handler # entry
  runtime: Nodejs10.15 # Cloud function runtime environment
  region: ap-hongkong # Area where the cloud function is located
  events: # the trigger
    - apigw: # Gateway trigger
        parameters:
          endpoints:
            - path: /
              method: GET

Copy the code

Configure our deploy script so that when we run NPM Run deploy, the package is packaged before deployment.

"scripts": {
    "start": "ts-node src/local.ts"."build": "ncc build src/index.ts"."deploy": "npm run build && sls deploy"
  },
Copy the code

When everything is ready, run NPM Run deploy and you can see that the cloud function has been successfully uploaded. It also helps us create a gateway trigger that triggers access functions directly through the URL

So let’s go to the functions console page, put in the function configuration, put in the running role, and then upload it to COS, and then we can get SecretKey and SecretID directly from the function running context, so we don’t have to write it in code, so it’s very convenient.

Let’s test the function manually

Good, it worked

You can see that COS already has the video files that we want to download, so XDM is convenient. I’ll take the time to get the video address through the gateway URL parameter, and I’ll leave that up to you. I will submit the code, you can directly Fork to their own warehouse development.

serverless-youtube-download

goodbye

Thanks for your support and I’ll see you next time.