pauloo27 / tiktok-live

A simple NodeJS application to download TikTok lives by the share URL.
GNU General Public License v3.0
62 stars 14 forks source link

not downloading some broadcasts #4

Open unkeyn opened 2 years ago

unkeyn commented 2 years ago

gives such an error:

URL > https://www.tiktok.com/@liulangzhe11/live Found live "": m3u8 URL: https://pull-hls-f16-tt02.tiktokcdn.com/stage/stream-3570039214190362986_or4/index.m3u8 flv URL: http://pull-flv-f16-tt02.tiktokcdn.com/stage/stream-3570039214190362986_or4/index.flv Writing live to 7121579726937885483.flv. Press Ctrl C to STOP. node:events:505 throw er; // Unhandled 'error' event ^

Error: getaddrinfo ENOTFOUND pull-flv-f16-tt02.tiktokcdn.com at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:71:26) Emitted 'error' event on ClientRequest instance at: at Socket.socketErrorListener (node:_http_client:454:9) at Socket.emit (node:events:527:28) at emitErrorNT (node:internal/streams/destroy:157:8) at emitErrorCloseNT (node:internal/streams/destroy:122:3) at processTicksAndRejections (node:internal/process/task_queues:83:21) { errno: -3008, code: 'ENOTFOUND', syscall: 'getaddrinfo', hostname: 'pull-flv-f16-tt02.tiktokcdn.com' }

forceware680 commented 1 year ago

C:\Users\Praz\Documents\GitHub\tiktok-live>node index.js https://www.tiktok.com/@redi.44/live?is_from_webapp=1 & sender_device=pc URL > https://www.tiktok.com/@redi.44/live?is_from_webapp=1 Found live "Meloww": m3u8 URL: https://pull-hls-f16-gcp01.tiktokcdn.com/game/stream-3282190472324317368/index.m3u8 flv URL: http://pull-flv-f16-gcp01.tiktokcdn.com/game/stream-3282190472324317368/index.flv Writing live to 7146005112224320282.flv. Press Ctrl C to STOP. node:events:491 throw er; // Unhandled 'error' event ^

Error: getaddrinfo ENOTFOUND pull-flv-f16-gcp01.tiktokcdn.com at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:109:26) Emitted 'error' event on ClientRequest instance at: at Socket.socketErrorListener (node:_http_client:481:9) at Socket.emit (node:events:513:28) at emitErrorNT (node:internal/streams/destroy:157:8) at emitErrorCloseNT (node:internal/streams/destroy:122:3) at processTicksAndRejections (node:internal/process/task_queues:83:21) { errno: -3008, code: 'ENOTFOUND', syscall: 'getaddrinfo', hostname: 'pull-flv-f16-gcp01.tiktokcdn.com' } 'sender_device' is not recognized as an internal or external command, operable program or batch file.

give some error i hope this dev continue this amazing project

pauloo27 commented 1 year ago

Can you provide more details? To me it worked just fine.

When does this error happens? Always?

forceware680 commented 1 year ago

image i don't know.. but i just follow the guide, always error. see my attachment

stubleu commented 1 year ago

It doesn't tend to work when there's punctuation in the username

pauloo27 commented 1 year ago

Thanks for the feedback. I cannot reproduce the problem, it works normally when a user has punctuation for me. I think the problem maybe related to region.

stubleu commented 1 year ago

In the last day or so I've been getting this for some users though you're right. Punctuation doesn't always play a factor, though I've seen it more often then not fail with a user with punctuation.

`Error: getaddrinfo ENOTFOUND pull-flv-f16-va01.ttlivecdn.com at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:66:26) Emitted 'error' event on ClientRequest instance at: at Socket.socketErrorListener (_http_client.js:427:9) at Socket.emit (events.js:314:20) at emitErrorNT (internal/streams/destroy.js:92:8) at emitErrorAndCloseNT (internal/streams/destroy.js:60:3) at processTicksAndRejections (internal/process/task_queues.js:84:21) { errno: 'ENOTFOUND', code: 'ENOTFOUND', syscall: 'getaddrinfo', hostname: 'pull-flv-f16-va01.ttlivecdn.com' }

dungtam73 commented 1 year ago

Thanks for the feedback. I cannot reproduce the problem, it works normally when a user has punctuation for me. I think the problem maybe related to region.

Have you solved this problem?

pauloo27 commented 1 year ago

Thanks for the feedback. I cannot reproduce the problem, it works normally when a user has punctuation for me. I think the problem maybe related to region.

Have you solved this problem?

I have not, I can't reproduce the problem =(

stubleu commented 1 year ago

I'm not a node dev so I cobbled together a rewrite to get it to take the m3u8 address and feed it to ffmpeg and haven't had any problems downloading from there.

ladamrkvicka commented 1 year ago

I'm not a node dev so I cobbled together a rewrite to get it to take the m3u8 address and feed it to ffmpeg and haven't had any problems downloading from there.

Hi, sorry to bother, can you please share your rewrite with me? I am sadly no developer, so i can't make these alterations by myself. Your help would be most appreciated. Thank you.

stubleu commented 1 year ago

I'm not a node dev so I cobbled together a rewrite to get it to take the m3u8 address and feed it to ffmpeg and haven't had any problems downloading from there.

Hi, sorry to bother, can you please share your rewrite with me? I am sadly no developer, so i can't make these alterations by myself. Your help would be most appreciated. Thank you.

After installing ffmpeg i cut out a lot of the index.js to this. Note that on line 21 it gives a directory to save it in. I also appended a timestamp to the session name because I found that the original would over-write the filename if it stopped and you reran it during the same session. Like i said, this is jinky.

` const fetch = require("node-fetch"); const fs = require("fs"); const http = require("http"); var shell = require('shelljs');

let url = https://tiktok.com/@ + process.argv[2] + /live;

fetch(url) .then(res => { return res.text(); }) .then(async (body) => { const roomId = body.match(/room_id=(\d+)/)[1]; const apiURL = https://www.tiktok.com/api/live/detail/?aid=1988&roomID=${roomId};

      const res = await (await fetch(apiURL)).json();
      const {title, liveUrl} = res.LiveRoomInfo;

      const flvUrl = liveUrl.replace("pull-hls", "pull-flv").replace("/playlist.m3u8", ".flv").replace("https", "http").replace(`.m3u8`, `.flv`);

    shell.exec(`ffmpeg -i ${liveUrl} -c copy ` + `c:/temp/tok/${roomId}` + Date.now() + `.mp4`);

    });

`

ladamrkvicka commented 1 year ago

Thank you. I will try this.

ladamrkvicka commented 1 year ago

I'm not a node dev so I cobbled together a rewrite to get it to take the m3u8 address and feed it to ffmpeg and haven't had any problems downloading from there.

Hi, sorry to bother, can you please share your rewrite with me? I am sadly no developer, so i can't make these alterations by myself. Your help would be most appreciated. Thank you.

After installing ffmpeg i cut out a lot of the index.js to this. Note that on line 21 it gives a directory to save it in. I also appended a timestamp to the session name because I found that the original would over-write the filename if it stopped and you reran it during the same session. Like i said, this is jinky.

` const fetch = require("node-fetch"); const fs = require("fs"); const http = require("http"); var shell = require('shelljs');

let url = https://tiktok.com/@ + process.argv[2] + /live;

fetch(url) .then(res => { return res.text(); }) .then(async (body) => { const roomId = body.match(/room_id=(\d+)/)[1]; const apiURL = https://www.tiktok.com/api/live/detail/?aid=1988&roomID=${roomId};

      const res = await (await fetch(apiURL)).json();
      const {title, liveUrl} = res.LiveRoomInfo;

      const flvUrl = liveUrl.replace("pull-hls", "pull-flv").replace("/playlist.m3u8", ".flv").replace("https", "http").replace(`.m3u8`, `.flv`);

      shell.exec(`ffmpeg -i ${liveUrl} -c copy ` + `c:/temp/tok/${roomId}` + Date.now() + `.mp4`);

    });

`

Hi, sorry for bothering again and spamming here. I tried running your rewrite, but i get this error. Probably I installed ffmpeg incorectly? Can you please advise once more? Thank you.

node:internal/modules/cjs/loader:959 throw err; ^

Error: Cannot find module 'shelljs' Require stack:

stubleu commented 1 year ago

I think you just have to install ShellJS with npm install -g shelljs

ladamrkvicka commented 1 year ago

I think you just have to install ShellJS with npm install -g shelljs

Thank you, i solved this by installing the shelljs to the tiktok-live folder, removing -g. But now i get another error:

TypeError: Cannot read properties of null (reading '1') at P:\Downloads\ttlrew\tiktok-live\index.js:13:43 at processTicksAndRejections (node:internal/process/task_queues:96:5) PS P:\Downloads\ttlrew\tiktok-live> node index.js https://www.tiktok.com/@xxxx/live P:\Downloads\ttlrew\tiktok-live\index.js:13 const roomId = body.match(/room_id=(\d+)/)[1]; ^

TypeError: Cannot read properties of null (reading '1') at P:\Downloads\ttlrew\tiktok-live\index.js:13:43 at processTicksAndRejections (node:internal/process/task_queues:96:5) PS P:\Downloads\ttlrew\tiktok-live>

Again I am so sorry for being such a bother... Can you help, hopefully for the last time?

stubleu commented 1 year ago

Right. Sorry, I changed the format for running the command. Now you just need to run node index.js <username> Where username is JUST the tiktok user's username. none of the url. It fills that all in for you.

ladamrkvicka commented 1 year ago

Right. Sorry, I changed the format for running the command. Now you just need to run node index.js <username> Where username is JUST the tiktok user's username. none of the url. It fills that all in for you.

Ah, I see. Now it works perfectly, thank you so much for your help and patience.

stubleu commented 1 year ago

Right. Sorry, I changed the format for running the command. Now you just need to run node index.js <username> Where username is JUST the tiktok user's username. none of the url. It fills that all in for you.

Ah, I see. Now it works perfectly, thank you so much for your help and patience.

No problem. Like I said, it's a dirty hack to the script but it works and stores the streams as mp4s.

pauloo27 commented 1 year ago

@stubleu

do you mind if you copy your rewrite and push it to master?

stubleu commented 1 year ago

:/ how do I do that? I don't really use git other than to clone repos

pauloo27 commented 1 year ago

:/ how do I do that? I don't really use git other than to clone repos

I will do it for you, thanks for the fix tho

ladamrkvicka commented 1 year ago

Hi,

just a few observations after a few weeks of use - i recommend keeping the .flv format over .mp4, because with shorter/interrupted broadcasts, mp4 gets very easily corrupted and unplayable. Also i had better results with streamlink over FFmpeg, mostly because ffmpeg on error just hangs, making it impossible to continuously check if the broadcaster is online. With streamlink you can use simple powershell script to check every minute or so if broadcast is online and record if it is.

stubleu commented 1 year ago

Hi,

just a few observations after a few weeks of use - i recommend keeping the .flv format over .mp4, because with shorter/interrupted broadcasts, mp4 gets very easily corrupted and unplayable. Also i had better results with streamlink over FFmpeg, mostly because ffmpeg on error just hangs, making it impossible to continuously check if the broadcaster is online. With streamlink you can use simple powershell script to check every minute or so if broadcast is online and record if it is.

That's curious. One of the problems I was having with the original script was anytime it'd pause by the user it would stop my capture. Sometimes that would trigger by detecting the user not there so the stream would autopause and close the capture. Now with the ffmpeg it only does it when the users hits pause.

What did you use with powershell to detect the stream?

ladamrkvicka commented 1 year ago

Very simple script.

node index.js <username> Start-sleep -seconds 60 & ".\<script filename>.ps1"

This will check every 60s if the stream is available. As I said, doesn't work with Ffmpeg but works with streamlink.

stubleu commented 1 year ago

I just did a test of the script and it still works for me. I thought that I had an issue so i threw the first line into cmd.exe -c "node index.js "

but after some troubleshooting and output it looks like it was a false positive from the live. That's something else that i'll have to start testing with but i was able to get that same ps1 script to run with ffmpeg. Waiting now for that stream to end to make sure it keeps running but don't see why it wouldn't.

stubleu commented 1 year ago

if you change it to $param1=$args[0] node index.js $param1 Start-sleep -seconds 60 & ".\.ps1" $param1 You can also use ./scriptname.ps1

forceware680 commented 1 year ago

Hi,

just a few observations after a few weeks of use - i recommend keeping the .flv format over .mp4, because with shorter/interrupted broadcasts, mp4 gets very easily corrupted and unplayable. Also i had better results with streamlink over FFmpeg, mostly because ffmpeg on error just hangs, making it impossible to continuously check if the broadcaster is online. With streamlink you can use simple powershell script to check every minute or so if broadcast is online and record if it is.

can u please complete tutor using this script via streamlink?

ladamrkvicka commented 1 year ago

Change the last line to

shell.exec(`streamlink` -o "p:/Downloads/ttlrew/tiktok-live/Rec/${roomId}_` + Date.now() + `.flv" "${liveUrl}" best`);

Change the path of course. You'll need to have Streamlink installed.

forceware680 commented 1 year ago

Change the last line to

shell.exec(`streamlink` -o "p:/Downloads/ttlrew/tiktok-live/Rec/${roomId}_` + Date.now() + `.flv" "${liveUrl}" best`);

Change the path of course. You'll need to have Streamlink installed.

got some error SyntaxError: missing ) after argument list ←[90m at Object.compileFunction (node:vm:360:18)←[39m ←[90m at wrapSafe (node:internal/modules/cjs/loader:1055:15)←[39m ←[90m at Module._compile (node:internal/modules/cjs/loader:1090:27)←[39m ←[90m at Object.Module._extensions..js (node:internal/modules/cjs/loader:1180:10)←[39m ←[90m at Module.load (node:internal/modules/cjs/loader:1004:32)←[39m ←[90m at Function.Module._load (node:internal/modules/cjs/loader:839:12)←[39m ←[90m at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)←[39m ←[90m at node:internal/main/run_main_module:17:47←[39m