Node.js에서 Youtube 동영상을 DL하고 저장 ytdl-core를 사용한 메모

Node.js에서 Youtube의 동영상 파일을 어쩔 수 없이 이야기로 조사하면 꽤 다양한 라이브러리가 나옵니다.

htps //w w. 음 pmjs. 이 m/세아 rch? q=요츠베 dl

이번에는 업데이트가 비교적 새롭기 때문에 유지 보수되고 있음을 기대할 수있는 ytdl-core라는 모듈을 사용해 보겠습니다. 사용해 본 분위기라면 ffmpeg를 이용하지 않아도 어느 정도 이용할 수 있을 것 같았습니다.

htps : // 기주 b. 코 m / 후 t / 그래서 - ytdl - 이것

덧붙여서 명령줄 도구 버전의 ytdl 도 있습니다.

그런 다음 내 동영상에서 시도합니다.

환경


  • Node.js 10.11.0
  • npm 6.4.1
  • macOS Mojave 10.4

  • 설치


    npm i ytdl-core
    

    DL만


    const fs = require('fs');
    const ytdl = require('ytdl-core');
    const BASE_PATH = `https://www.youtube.com/watch?v=`;
    
    const youtubeId = `9CHiwJhx3qw`; //DLするYoutube動画のID(urlのv=の後ろの部分11桁)
    const url = BASE_PATH+youtubeId;
    
    ytdl(url).pipe(fs.createWriteStream(`${youtubeId}.mp4`));
    

    진행 표시 및 동영상 정보 획득



    DL이 완료되었을 때의 이벤트를 취득하고 싶을 때는 이하와 같이 'end' 의 이벤트로 핸들링할 수 있습니다.

    여기 샘플 코드 2개를 참고로 하고 있습니다.
    htps : // 기주 b. 이 m / 훗 t / 그래서 - ytdl - 이것 / b ぉ b / 뭐 r / 에 mp ぇ / p 로그 뻗어 s. js
    htps : // 기주 b. 이 m / 훗 t / 그래서 - ytdl - 이것 / b ぉ b / 뭐 r / 에 ぁ ぇ / 게 t_ んふぉ. js

    이번은 readline 도 표시용으로 사용합니다.
    npm i readline
    

    app.js
    const fs = require('fs');
    
    const ytdl = require('ytdl-core');
    const readline = require('readline'); //表示用途
    
    const BASE_PATH = `https://www.youtube.com/watch?v=`;
    
    const youtubeId = `9CHiwJhx3qw`; //DLするYoutube動画のID(urlのv=の後ろの部分11桁)
    const url = BASE_PATH+youtubeId;
    
    const video = ytdl(url,{filter: (format) => format.container === 'mp4' });
    
    let starttime;
    
    video.pipe(fs.createWriteStream(`${youtubeId}.mp4`));
    
    video.once('response', () => starttime = Date.now());
    
    video.on('progress', (chunkLength, downloaded, total) => {
        const floatDownloaded = downloaded / total;
        const downloadedMinutes = (Date.now() - starttime) / 1000 / 60;
        readline.cursorTo(process.stdout, 0);
        process.stdout.write(`${(floatDownloaded * 100).toFixed(2)}% downloaded`);
        process.stdout.write(`(${(downloaded / 1024 / 1024).toFixed(2)}MB of ${(total / 1024 / 1024).toFixed(2)}MB)\n`);
        process.stdout.write(`running for: ${downloadedMinutes.toFixed(2)}minutes`);
        process.stdout.write(`, estimated time left: ${(downloadedMinutes / floatDownloaded - downloadedMinutes).toFixed(2)}minutes `);
        readline.moveCursor(process.stdout, 0, -1);
    });
    
    video.on('end', () => {
        process.stdout.write('\n\n');
    
        //DLしたYoutube動画の情報
        ytdl.getInfo(youtubeId, (err, info) => {
            if (err) throw err;
    
            console.log('\n動画情報もろもろ');
            console.log(info.player_response.videoDetails);
    
            console.log('\n動画タイトル');
            console.log(info.player_response.videoDetails.title);
    
            console.log('\n秒数');
            console.log(info.player_response.videoDetails.lengthSeconds);
    
            console.log('\nサムネイル');
            console.log(info.player_response.videoDetails.thumbnail);
        });
    });
    

    결과는 이런 느낌
    $ node app.js
    
    動画情報もろもろ
    { videoId: '9CHiwJhx3qw',
      title: '【検証】うんこボタンであのイタズラは成功するか!?【予想外の展開】',
      lengthSeconds: '288',
      keywords: [ 'iot', 'iotlt', 'うんこボタン', 'ドッキリ', 'イタズラ', '電子工作' ],
      channelId: 'UC42TOX3Ff7H0iORoPoBkAcg',
      isCrawlable: true,
      thumbnail: { thumbnails: [ [Object], [Object], [Object], [Object] ] },
      viewCount: '298',
      author: 'どっとすたぢお',
      isLiveContent: false }
    
    動画タイトル
    【検証】うんこボタンであのイタズラは成功するか!?【予想外の展開】
    
    秒数
    288
    
    サムネイル
    { thumbnails:
       [ { url:
            'https://i.ytimg.com/vi/9CHiwJhx3qw/hqdefault.jpg?sqp=-oaymwEiCKgBEF5IWvKriqkDFQgBFQAAAAAYASUAAMhCPQCAokN4AQ==&rs=AOn4CLAS-n8-TmsSRbr_gbKFLAuBY22Rkg',
           width: 168,
           height: 94 },
         { url:
            'https://i.ytimg.com/vi/9CHiwJhx3qw/hqdefault.jpg?sqp=-oaymwEiCMQBEG5IWvKriqkDFQgBFQAAAAAYASUAAMhCPQCAokN4AQ==&rs=AOn4CLA0WQFxu5lN1nHd3S4qYabeCvioKA',
           width: 196,
           height: 110 },
         { url:
            'https://i.ytimg.com/vi/9CHiwJhx3qw/hqdefault.jpg?sqp=-oaymwEjCPYBEIoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLA3j-N0ahl91bywiKcv7vGOiD_3Pw',
           width: 246,
           height: 138 },
         { url:
            'https://i.ytimg.com/vi/9CHiwJhx3qw/hqdefault.jpg?sqp=-oaymwEjCNACELwBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLBL4Tit-bNE3WbNMitKo2TdGrMu-A',
           width: 336,
           height: 188 } ] }
    

    썸네일을 잡을 수있는 재미 있습니다.



    기타



    정말 mp4가 아니고 음원만의 mp3을 찍고 싶었지만 ffmpeg가 필요하다고 하는 것과, README 를 보는 한 highestaudio 이나 audioonly 파일이 망가져 버리는 현상이 되었다(수수께끼) 때문에 우선 mp4로 시험해 보았습니다.

    바이너리가 망가지는 현상은 옵션의 지정 방법이 좋지 않은 것 같은 생각이 들기 때문에 시간이 있으면 재챌린지해 보고 싶은 기분

    좋은 웹페이지 즐겨찾기