• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

陈文管的博客

分享有价值的内容

  • Android
  • Affiliate
  • SEO
  • 前后端
  • 网站建设
  • 自动化
  • 开发资源
  • 关于

在线视频转音频后端服务搭建

2024年11月19日发布 | 最近更新于 2024年11月19日

在线视频转音频 https://yttomp3.media/ 和 https://youtubetomp3converter.media/ 两个工具开始是根据Cobalt提供的接口实现的,在这个项目升级之后关闭了免费的接口,所以需要自己拉取Git项目搭建一个后端服务。

一、服务平台选择

对比了下各个平台的费用,搭建后端服务的平台直接使用赞助Cobalt项目的RoyaleHosting,相比其他平台性价比最高,需要注意的是,在RoyaleHosting平台注册账号的时候不要使用iCloud的邮箱,iCloud屏蔽了这个平台的邮件发送服务,无法使用iCloud的邮箱激活账号,如果不慎使用iCloud邮箱,可以提一个Ticket(https://royalehosting.net/dashboard/tickets)给服务支持人员。

服务器的地址最好是选美国区域,如果选错了,也可以提一个Ticket去修改。

服务器的系统选择Ubuntu 22.04版本。

考虑到后续的访问量,选择4核4G内存的配置。

二、环境搭建配置

在创建服务钱,先购买一个域名,阿里云或namecheap都可以,配置下二级域名,比如购买的域名是xxx.com,二级域名参数配置成api.xxx.com,添加二级域名的A记录到购买的服务器IP地址。

按照Cobalt的文档操作:https://github.com/imputnet/cobalt/blob/main/docs/run-an-instance.md

1. 安装Docker

根据文章教程操作:How to Install and Use Docker

2. 安装Docker Compose

根据文章教程操作:How To Install Docker Compose

3. 创建Cobalt项目目录

mkdir cobalt

4. 进入目录添加docker-compose.yml配置文件

进入cobalt目录

cd cobalt

添加配置文件,执行如下命令进入编辑模式

sudo vim docker-compose.yml

拷贝如下内容,替换API_URL参数为自己的二级域名,如果cookies.json文件还没配置,就先注释掉

COOKIE_PATH: "/cookies.json"

和

volumes:            
   - ./cookies.json:/cookies.json

Ctrl+V 粘贴,之后按ESC,输入 :wq 保存退出。

services:
    cobalt-api:
        image: ghcr.io/imputnet/cobalt:10

        init: true
        read_only: true
        restart: unless-stopped
        container_name: cobalt-api

        ports:
            #- 9000:9000/tcp
            # if you use a reverse proxy (such as nginx),
            # uncomment the next line and remove the one above (9000:9000/tcp):
            - 127.0.0.1:9000:9000

        environment:
            # replace https://api.url.example/ with your instance's url
            # or else tunneling functionality won't work properly
            API_URL: "https://api.XXX.com/"
            # if you want to use cookies for fetching data from services,
            # uncomment the next line & volumes section
            COOKIE_PATH: "/cookies.json"

            # it's recommended to configure bot protection or api keys if the instance is public,
            # see /docs/protect-an-instance.md for more info

            # see /docs/run-an-instance.md for more variables that you can use here

        labels:
            - com.centurylinklabs.watchtower.scope=cobalt

        # uncomment only if you use the COOKIE_PATH variable
        volumes:
            - ./cookies.json:/cookies.json

    # watchtower updates the cobalt image automatically
    watchtower:
        image: ghcr.io/containrrr/watchtower
        restart: unless-stopped
        command: --cleanup --scope cobalt --interval 900 --include-restarting
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock

cookies.json文件主要是配置Youtube的Token参数。如果不需要支持Youtube平台的转换和下载可以不配置。

如果还没配置HTTPS的环境,可以先注释掉- 127.0.0.1:9000:9000,恢复- 9000:9000/tcp,等配置nginx代理之后再恢复回来。

5. 启动Cobalt项目容器

docker compose up -d

三、配置HTTPS代理

1. 安装 Certbot

Certbot 是用于获取和管理 SSL 证书的工具,您可以通过以下命令安装(Ubuntu/Debian环境):

sudo apt update
sudo apt install certbot python3-certbot-nginx

2. 获取 SSL 证书

使用 Certbot 为您的域名获取 SSL 证书,yourdomain替换为自己的域名:

sudo certbot --nginx -d api.yourdomain.com

这将自动为您配置 Nginx 以支持 HTTPS,并获取 Let’s Encrypt 提供的 SSL 证书。Certbot 会提示您输入电子邮件地址以及是否同意服务条款。

3. 配置自动续期

Certbot 会自动配置证书续期,但您可以手动运行以下命令以测试续期:

sudo certbot renew --dry-run

4. 检查 Nginx 配置

Certbot 会自动更新 Nginx 配置,您可以检查 /etc/nginx/sites-available/api.yourdomain.com 是否包含类似以下内容的配置:

server {
    listen 80;
    server_name api.yourdomain.com;

    # Redirect all HTTP requests to HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name api.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://localhost:9000;  # 替换为 Cobalt 使用的端口
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

5. 重新加载 Nginx

完成配置后,重新加载 Nginx 以使更改生效:

sudo systemctl reload nginx

6. 测试 HTTPS

上面都配置好之后,恢复- 127.0.0.1:9000:9000的配置,注释掉- 9000:9000/tcp,执行下面两条命令,重启下Docker:

docker-compose down 
docker-compose up -d

在浏览器中访问 https://api.yourdomain.com,确认 HTTPS 是否可以正常访问。

通过这些步骤,您就可以为 api.yourdomain.com 配置 HTTPS,使其安全访问。

四、配置Youtube Token

1. 先clone项目到本地电脑

git clone https://github.com/imputnet/cobalt.git

2. 进入项目目录,安装下环境配置

cd cobalt/api
pnpm install

3. 打开Chrome无痕浏览模式,避免账号关联

打开 https://www.google.com/device 地址

用你专门申请的Google账号登录(比如使用网易邮箱申请一个Google Gmail账号),账号激活如果需要美区电话号码认证,可以使用接码平台(https://sms-activate.guru/)购买一个十几分钟使用期限的美区电话号码。

从Cobalt项目的issue信息来看,当账号调用Youtube接口次数比较大的时候,账号容易被封,所以为了避免账号损失,最好不要使用私人账号,额外申请一个或多个账号用于这个项目的使用。

4. 执行生成Token命令

pnpm -C api token:youtube

把控制台输出的类似如下的信息拷贝出来:

"access_token=xxxxxxx; refresh_token=xxxxxxx; scope=https://www.googleapis.com/auth/youtube-paid-content https://www.googleapis.com/auth/youtube; token_type=Bearer; expiry_date=2024-11-11T02:19:43.303Z"

配置到cookies.json文件,配置示例如下:

{
    "youtube_oauth": [
        "access_token=xxxxxxx; refresh_token=xxxxxxx; scope=https://www.googleapis.com/auth/youtube-paid-content https://www.googleapis.com/auth/youtube; token_type=Bearer; expiry_date=2024-11-11T02:19:43.303Z"
    ]
}

如果有多个Token可以用英文字符逗号隔开,之后打开docker-compose.yml配置文件里面关于cookies.json的两个配置,重启下Docker实例就可以立即生效。

Token的有效期是一天,Cobalt会自动申请更新Token,在第一次配置完成之后就无需关注,除非账号被封需要重新执行下以上步骤。

最后这个步骤是最难搞的,个人测试,即使开了“科学上网”,打开了系统全局代理,也没法访问Youtube的API域名地址,ping这个地址直接出现超时异常。后面谷歌搜索了其他生成Youtube Token的方法,虽然可以生成Token,但是不能用在这个项目的配置上。最后只好找在美国的大学同学帮操作了下,顺利生成了Token,同学说可以搞个Mac Mini,直接把路由配置成“科学上网”的方式,未做测试,这个不知道是否可以行。

除了上面这些,也可以增加下保护实例的配置:https://github.com/imputnet/cobalt/blob/main/docs/protect-an-instance.md

五、刷新Token的JS脚本

如果需要使用其他方式获取Token,可以参考以下这两篇文章,这边的方式获取的Token不能用在Cobalt项目上:

Retrieve YouTube API v3 key with Node.js

Youtube V3 QuickStart NodeJS

结合下面的JS脚本来获取和刷新cookies.json的Token内容。

var fs = require('fs');
var readline = require('readline');
var { google } = require('googleapis');
var OAuth2 = google.auth.OAuth2;

var TOKEN_PATH = './cookies.json';

// Load client secrets from a local file (client_secret.json).
fs.readFile('client_secret.json', function processClientSecrets(err, content) {
  if (err) {
    console.log('Error loading client secret file:', err);
    return;
  }
  // Authorize a client with the loaded credentials, then call the YouTube API.
  authorize(JSON.parse(content), getNewTokenAndUpdateFile);
});

/**
 * Create an OAuth2 client with the given credentials, and then execute the
 * given callback function.
 *
 * @param {Object} credentials The authorization client credentials.
 * @param {function} callback The callback to call with the authorized client.
 */
function authorize(credentials, callback) {
  var clientSecret = credentials.web.client_secret;
  var clientId = credentials.web.client_id;
  var redirectUrl = credentials.web.redirect_uris[0];
  var oauth2Client = new OAuth2(clientId, clientSecret, redirectUrl);

  // Check if we have previously stored a token.
  fs.readFile(TOKEN_PATH, function (err, tokenData) {
    if (err) {
      getNewToken(oauth2Client, callback);
    } else {
      var token = JSON.parse(tokenData).youtube_oauth[0];
      oauth2Client.credentials = JSON.parse(token);
      callback(oauth2Client);
    }
  });
}

/**
 * Get and store new token after prompting for user authorization.
 *
 * @param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
 * @param {function} callback The callback to call with the authorized client.
 */
function getNewToken(oauth2Client, callback) {
  var authUrl = oauth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: ['https://www.googleapis.com/auth/youtube.readonly'],
    prompt: 'consent' // Ensures that a refresh token is returned
  });
  console.log('Authorize this app by visiting this url:', authUrl);
  var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });
  rl.question('Enter the code from that page here: ', function (code) {
    rl.close();
    oauth2Client.getToken(code, function (err, token) {
      if (err) {
        console.log('Error while trying to retrieve access token', err);
        return;
      }
      oauth2Client.credentials = token;
      storeToken(token);
      callback(oauth2Client);
    });
  });
}

/**
 * Store the token in the cookies.json file under the youtube_oauth field.
 *
 * @param {Object} token The token to store.
 */
function storeToken(token) {
  fs.readFile(TOKEN_PATH, (err, data) => {
    var updatedData = { youtube_oauth: [] };

    if (!err) {
      try {
        updatedData = JSON.parse(data);
      } catch (e) {
        console.error('Error parsing cookies.json:', e);
      }
    }

    // Replace the youtube_oauth field with the new token.
    updatedData.youtube_oauth = [JSON.stringify(token)];

    fs.writeFile(TOKEN_PATH, JSON.stringify(updatedData, null, 2), (err) => {
      if (err) {
        console.error('Error writing token to file:', err);
      } else {
        console.log('Token stored to', TOKEN_PATH);
      }
    });
  });
}

/**
 * Refreshes the access token and updates the cookies.json file.
 *
 * @param {google.auth.OAuth2} oauth2Client The OAuth2 client.
 */
function getNewTokenAndUpdateFile(oauth2Client) {
  oauth2Client.refreshAccessToken((err, tokens) => {
    if (err) {
      console.error('Error refreshing access token:', err);
      return;
    }
    console.log('New access token obtained:', tokens.access_token);
    oauth2Client.credentials = tokens;
    storeToken(tokens);
  });
}

在 VPS 服务器上,你可以使用 cron 作业来配置定时任务,以每 55 分钟执行一次 generateNewToken.js 脚本来获取新的 Token。以下是具体步骤:

1. 检查 Node.js 可执行路径

确保在 cron 中可以正确调用 node。运行以下命令获取 Node.js 的可执行路径:

which node

通常输出类似 /usr/bin/node 或 /usr/local/bin/node。这个路径将在 cron 作业中使用。

2. 使用 pwd 命令查看当前路径

如果你在终端中处于 generateNewToken.js 文件所在的文件夹中,运行以下命令可以查看当前路径:

pwd

3. 编辑 crontab 文件

使用以下命令编辑 crontab 文件:

crontab -e

4. 添加 cron 作业

在 crontab 文件中,添加以下行,每 55 分钟运行一次 generateNewToken.js 脚本。将 <path-to-your-script> 替换为第2步中获取的 generateNewToken.js 文件的绝对路径,<path-to-node> 替换为第 1 步中获取的 Node.js 路径。

*/55 * * * * <path-to-node> <path-to-your-script>/generateNewToken.js >> <path-to-your-script>/generateNewToken.log 2>&1

解释

  • */55 * * * *:每 55 分钟运行一次任务。
  • <path-to-node>:Node.js 的绝对路径。
  • <path-to-your-script>/generateNewToken.js:脚本的绝对路径。
  • >> <path-to-your-script>/generateNewToken.log 2>&1:将输出和错误日志重定向到 generateNewToken.log 文件。

5. 保存和退出 crontab

编辑完成后,保存并退出编辑器。cron 将自动加载和应用新的配置。

6. 检查 cron 作业是否已配置

运行以下命令,验证 cron 作业已成功添加:

crontab -l

7. 查看日志文件(可选)

检查 generateNewToken.log 文件,确保任务按预期运行,并调试任何潜在的问题:

tail -f <path-to-your-script>/generateNewToken.log

补充建议

  • 权限:确保 generateNewToken.js 文件具有可执行权限,可以使用 chmod +x generateNewToken.js 赋予权限。
  • 环境变量:如果 generateNewToken.js 依赖特定的环境变量,确保 cron 作业的环境中设置了这些变量,或在脚本中加载 .env 文件。

通过上述步骤,你可以在 VPS 上配置一个定时任务,每 55 分钟自动运行 generateNewToken.js 脚本,以获取新的 YouTube API 访问令牌。

扩展阅读:

在线视频转音频工具网站已上线

博客公众号

微信公众号

转载请注明出处:陈文管的博客 – 在线视频转音频后端服务搭建

文章目录

  • 一、服务平台选择
  • 二、环境搭建配置
    • 1. 安装Docker
    • 2. 安装Docker Compose
    • 3. 创建Cobalt项目目录
    • 4. 进入目录添加docker-compose.yml配置文件
    • 5. 启动Cobalt项目容器
  • 三、配置HTTPS代理
    • 1. 安装 Certbot
    • 2. 获取 SSL 证书
    • 3. 配置自动续期
    • 4. 检查 Nginx 配置
    • 5. 重新加载 Nginx
    • 6. 测试 HTTPS
  • 四、配置Youtube Token
    • 1. 先clone项目到本地电脑
    • 2. 进入项目目录,安装下环境配置
    • 3. 打开Chrome无痕浏览模式,避免账号关联
    • 4. 执行生成Token命令
  • 五、刷新Token的JS脚本
    • 1. 检查 Node.js 可执行路径
    • 2. 使用 pwd 命令查看当前路径
    • 3. 编辑 crontab 文件
    • 4. 添加 cron 作业
    • 5. 保存和退出 crontab
    • 6. 检查 cron 作业是否已配置
    • 7. 查看日志文件(可选)
    • 补充建议
博客公众号

闽ICP备18001825号-1 · Copyright © 2025 · Powered by chenwenguan.com