Giter VIP home page Giter VIP logo

twspace-dl's Introduction

Twspace-dl

PyPI PyPI DLs Github Releases DLs

A python module to download twitter spaces.

Screensots

GUI

general tab input tab running tab success pop up

CLI

help running

Requirements

  • ffmpeg if not using portable binaries.
  • A logged in user's cookies file exported from Twitter in the Netscape format.

Install

GUI

Use this if you're not sure.

From portable binaries

Windows

From source

pip install git+https://github.com/HoloArchivists/twspace-dl@gooey

CLI

From portable binaries

Windows

From PyPI

pip install twspace-dl

From source

pip install git+https://github.com/HoloArchivists/twspace-dl

Usage

twspace_dl -i space_url -c COOKIE_FILE
With binaries

Windows

.\twspace_dl.exe -i space_url -c COOKIE_FILE

Features

Here's the output of the help option

usage: twspace_dl [-h] [-v] [-s] [-k] [-l] -c COOKIE_FILE
                  [-i SPACE_URL | -U USER_URL] [-d DYN_URL] [-f URL] [-M PATH]
                  [-o FORMAT_STR] [-m] [-p] [-u] [--write-url URL_OUTPUT] [-e]

Script designed to help download twitter spaces

options:
  -h, --help            show this help message and exit
  -v, --verbose
  -s, --skip-download
  -k, --keep-files
  -l, --log             create logfile
  -c COOKIE_FILE, --input-cookie-file COOKIE_FILE
                        cookies file in the Netscape format. The specs of the
                        Netscape cookies format can be found here:
                        https://curl.se/docs/http-cookies.html. The cookies
                        file is now required due to the Twitter API change
                        that prohibited guest user access to Twitter API
                        endpoints on 2023-07-01.

input:
  -i SPACE_URL, --input-url SPACE_URL
  -U USER_URL, --user-url USER_URL
  -d DYN_URL, --from-dynamic-url DYN_URL
                        use the dynamic url for the processes(useful for ended
                        spaces) example: https://prod-fastly-ap-northeast-
                        1.video.pscp.tv/Transcoding/v1/hls/zUUpEgiM0M18jCGxo2e
                        SZs99p49hfyFQr1l4cdze-Sp4T-
                        DQOMMoZpkbdyetgfwscfvvUkAdeF-
                        I5hPI4bGoYg/non_transcode/ap-northeast-1/periscope-
                        replay-direct-prod-ap-northeast-1-public/audio-
                        space/dynamic_playlist.m3u8?type=live
  -f URL, --from-master-url URL
                        use the master url for the processes(useful for ended
                        spaces) example: https://prod-fastly-ap-northeast-
                        1.video.pscp.tv/Transcoding/v1/hls/YRSsw6_P5xUZHMualK5
                        -ihvePR6o4QmoZVOBGicKvmkL_KB9IQYtxVqm3P_vpZ2HnFkoRfar4
                        _uJOjqC8OCo5A/non_transcode/ap-northeast-1/periscope-
                        replay-direct-prod-ap-northeast-1-public/audio-
                        space/master_playlist.m3u8
  -M PATH, --input-metadata PATH
                        use a metadata json file instead of input url (useful
                        for very old ended spaces)

output:
  -o FORMAT_STR, --output FORMAT_STR
  -m, --write-metadata  write the full metadata json to a file
  -p, --write-playlist  write the m3u8 used to download the stream(e.g. if you
                        want to use another downloader)
  -u, --url             display the master url
  --write-url URL_OUTPUT
                        write master url to file
  -e, --embed-cover     embed user avatar as cover art

Format

You can use the following identifiers for the formatting

%(title)s
%(id)s
%(start_date)s
%(creator_name)s
%(creator_screen_name)s
%(url)s
%(creator_id)s

Example: [%(creator_screen_name)s]-%(title)s|%(start_date)s

Known Errors

Changing ID3 metadata in HLS audio elementary stream is not implemented....

This is an error in ffmpeg that does not affect twspace_dl at all as far as I know.

Service

To run as a systemd service please refer to https://github.com/HoloArchivists/twspace-dl/blob/main/SERVICE.md

Docker

Run once

docker run --rm -v .:/output holoarchivists/twspace-dl -i space_url

Run as monitoring service

  1. Download the docker-compose.yml, .env, monitor.sh files and put them in a folder named twspace-dl.
  2. Edit .env and fill in the Twitter username you want to monitor.
  3. Put a cookies file into the folder and named it cookies.txt.
  4. docker-compose up -d

twspace-dl's People

Contributors

dependabot[bot] avatar eggplants avatar exzhawk avatar ionic-bond avatar jim60105 avatar migimigi avatar mikelei8291 avatar mirusu400 avatar patcon avatar risingfog avatar ryu1845 avatar vubui avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

twspace-dl's Issues

I faced a problem

C:>.\twspace_dl -i https://twitter.com/i/spaces/1vAxRkepLArKl
Traceback (most recent call last):
File "C:\Users\GLNAZP1\AppData\Local\Temp\ONA8AA1_main_.py", line 142, in
File "C:\Users\GLNAZP1\AppData\Local\Temp\ONA8AA1_main_.py", line 133, in main
File "C:\Users\GLNAZP1\AppData\Local\Temp\ONA8AA1\twspace_dl\TwspaceDL.py", line 226, in download
File "C:\Users\GLNAZP1\AppData\Local\Temp\ONA8AA1\twspace_dl\TwspaceDL.py", line 216, in write_playlist
FileNotFoundError: [Errno 2] No such file or directory: '\[S\.G\.\]Traders\ Talk\ πŸŽ™\-1vAxRke pLArKl.m3u8'

I faced a problem like this

Add ffmpeg to portable binary

Is your feature request related to a problem? Please describe.
Reduce friction to neophyte users by removing a step

Describe the solution you'd like
Add ffmpeg binary to the portable exe

Describe alternatives you've considered
None

Additional context
Cf. #57

Write tests

Is your feature request related to a problem? Please describe.
I'm always frustrated when IΒ release multiple time just to fix a stupid bug that escapes a simple manual test.

Describe the solution you'd like
Write automated tests so this doesn't happen again

Describe alternatives you've considered
Just test every possibility of failure from the new features that come on top of my head

Additional context
cfr latest releases

File is incomplete after space end.

Hi,
I'm using your old script
It's my first time I can use it on a live space. The file after space end is only the beginning. I think merging the 2 files have problem and it deleted all tmp file so I can not undo the action.
image
Did problem fixed on your new version ?
And can I set default setting for --keep-files when run it ?

Thank you.

Monitoring service won't download unless there's a user tweet

Is your feature request related to a problem? Please describe.
The user whose spaces I want to monitor won't tweet about their spaces so the program doesn't notice them.

Describe the solution you'd like
If possible, could you add an option to monitor for spaces that doesn't rely on tweets?

When the host is a protected account, twpace_dl will refuse to work.

When the host is a protected account, twpace_dl will refuse to work.

Output like this:

Traceback (most recent call last):
  File "/home/will/.local/bin/twspace_dl", line 8, in <module>
    sys.exit(main())
  File "/home/will/.local/lib/python3.10/site-packages/twspace_dl/__main__.py", line 231, in main
    args.func(args)
  File "/home/will/.local/lib/python3.10/site-packages/twspace_dl/__main__.py", line 91, in space
    twspace = Twspace.from_space_url(args.input_url)
  File "/home/will/.local/lib/python3.10/site-packages/twspace_dl/twspace.py", line 181, in from_space_url
    return cls(cls._metadata(space_id))
  File "/home/will/.local/lib/python3.10/site-packages/twspace_dl/twspace.py", line 35, in __init__
    creator_info = root["creator_results"]["result"]["legacy"]  # type: ignore
KeyError: 'legacy'

Add 2FA to login

Is your feature request related to a problem? Please describe.
Right now the login subcommand doesn't run successfully on my account. The error displaying the need for authentication code which IΒ have indeed received.

Describe the solution you'd like
Prompt the user for 2FA code (e.g. using input())

Describe alternatives you've considered
None

Additional context
None

No guest token found after five retry.

Describe the bug
Always get RuntimeError: No guest token found after five retry in a few days.

To Reproduce
twspace_dl -U https://twitter.com/some_user

Expected behavior
Work normally

Output
If applicable, add the output of the command to help explain your problem.

Traceback (most recent call last):er:4
  File "/home/epix/.local/bin/twspace_dl", line 8, in <module>
    sys.exit(main())
  File "/home/epix/.local/lib/python3.9/site-packages/twspace_dl/__main__.py", line 120, in main
    twspace_dl = TwspaceDL.from_user_tweets(args.user_url, args.output)
  File "/home/epix/.local/lib/python3.9/site-packages/twspace_dl/TwspaceDL.py", line 39, in from_user_tweets
    user_id = TwspaceDL.user_id(url)
  File "/home/epix/.local/lib/python3.9/site-packages/twspace_dl/TwspaceDL.py", line 123, in user_id
    "x-guest-token": TwspaceDL.guest_token(),
  File "/home/epix/.local/lib/python3.9/site-packages/twspace_dl/TwspaceDL.py", line 146, in guest_token
    raise RuntimeError("No guest token found after five retry")
RuntimeError: No guest token found after five retry

Desktop (please complete the following information):

  • OS: Arch
  • Version commit dc38028
  • Installation method git

Additional context
Twitter may be changing the API. Need a new way to get guest tokens.
some reference:

JustAnotherArchivist/snscrape#326 (comment)
JustAnotherArchivist/snscrape#325 (comment)
JustAnotherArchivist/snscrape@0336ce1

Will try referred methods myself if I have some spare time.

Can't download from direct spaces link nor user

Hi, I am using this script on Ubuntu 20.04.2.

I have installed the script from PyPI, but the script returns the following error when I try to download from a live twitter spaces (direct link) or user URL:
image

Is there anything I can do to fix it? Seems like I am the only one facing this issue so far. I am not sure is it due to some dependencies or other factors.

Also, when downloading using -U, some users are not being shown as live even thought the Spaces is still live. I made sure the user selected is the Host of the spaces.

Introduce development tools

Is your feature request related to a problem? Please describe.
Need some tools for making this project more maintainable and easier to develop.

Describe the solution you'd like
Introduce:

  • formatter (i.e. black, isort, ...)
  • linter (i.e. flake8, mypy, ...)
  • CI workflows to execute of these tools
  • configuration of poetry.dev-dependencies and formatting/linting rules in pyproject.toml

macOS issues

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
python3 ./twspace_dl/__main__.py -i https://twitter.com/i/spaces/1MYxNnkdkPPxw -v

Expected behavior
begin to download the space audio.

Output
If applicable, add the output of the command to help explain your problem.


2022-06-18 02:27:50,086 [DEBUG] Starting new HTTPS connection (1): api.twitter.com:443
2022-06-18 02:27:50,718 [DEBUG] https://api.twitter.com:443 "POST /1.1/guest/activate.json HTTP/1.1" 200 62
2022-06-18 02:27:50,727 [DEBUG] Starting new HTTPS connection (1): twitter.com:443
2022-06-18 02:27:51,452 [DEBUG] https://twitter.com:443 "POST /i/api/1.1/onboarding/task.json?flow_name=login HTTP/1.1" 200 246
2022-06-18 02:27:51,665 [DEBUG] https://twitter.com:443 "POST /i/api/1.1/onboarding/task.json HTTP/1.1" 200 786
2022-06-18 02:27:51,856 [DEBUG] https://twitter.com:443 "POST /i/api/1.1/onboarding/task.json HTTP/1.1" 400 76
Traceback (most recent call last):
  File "./twspace_dl/__main__.py", line 726, in login
    self.flow_token = request_flow.json()["flow_token"]
KeyError: 'flow_token'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "./twspace_dl/__main__.py", line 1009, in <module>
    main()
  File "./twspace_dl/__main__.py", line 1004, in main
    args.func(args)
  File "./twspace_dl/__main__.py", line 849, in space
    auth_token = Login(args.username, args.password,
  File "./twspace_dl/__main__.py", line 728, in login
    raise RuntimeError("Error identifying user:",
RuntimeError: ('Error identifying user:', {'errors': [{'code': 366, 'message': 'Missing data.'}]})

Desktop (please complete the following information):

  • mbp Monsterey 12.3 python3.8.9 64bit
  • Version [e.g. 2022.6.10]
  • Installation method (pip)

Additional context
when I use poetry or pip:

poetry run twspace-dl -i https://twitter.com/i/spaces/1MYxNnkdkPPxw

  FileNotFoundError

  [Errno 2] No such file or directory: b'/Users/diven/.rvm/bin/twspace-dl'

twspace-dl is not in command, so I run it in source code lib

Handle lack of metadata

Is your feature request related to a problem? Please describe.
Currently twspace_dl fails when running with only a master url or a dynamic url.

Describe the solution you'd like
Add a flag for no metadata or handle it by default

Describe alternatives you've considered
N/a

Additional context
Multiple complaints have already been formed

`--keep-files` doesn't actually work

Describe the bug
--keep-files flag doesn't work, at least not in a way I expected (there is no description; but I assume it means to keep all the temp files).

From the code:

        finally:
            if not args.keep_files and os.path.exists(twspace_dl.tempdir.name):
                twspace_dl.tempdir.cleanup()

It is supposed to only cleanup() if not args.keep_files, but twspace_dl.tempdir is going to automatically clean itself either way due to the nature of how TemporaryDirectory works.

To Reproduce
python -m twspace_dl -U XXX --keep-files

Expected behavior
A clear and concise description of what you expected to happen.

Desktop (please complete the following information):

  • OS: Windows, python 3.8
  • Version master
  • Installation method (binary, pip, or other) source

Option to upload downloaded space to S3 or other storages

Is your feature request related to a problem? Please describe.
This is more like a nice to have. But I think it'd be great if we have an option to automatically upload downloaded content to say an s3 bucket. This is useful when others use twspace-dl to build something like a webapp or just want things organized nicely in S3.

Describe the solution you'd like

  1. Add an option to take a S3 bucket
  2. A module to use S3 SDK to upload to the S3 bucket with credentials from .env

Describe alternatives you've considered
Upload manually

Happy to help if the approach can be aligned :)

"list index out of range" if the cookies.txt file don't contain "auth_token" record

Describe the bug
list index out of range if the cookies.txt file don't contain auth_token record

To Reproduce
Pass an empty cookies.txt file in it.

Expected behavior
I suggest making errors easier to read.
Or outputting warnings and fallback to unlogined methods.

Output

Traceback (most recent call last):
  File "/venv/bin/twspace_dl", line 8, in <module>
    sys.exit(main())
  File "/venv/lib/python3.10/site-packages/twspace_dl/__main__.py", line 116, in main
    args.func(args)
  File "/venv/lib/python3.10/site-packages/twspace_dl/__main__.py", line 153, in twspace
    auth_token = load_from_file(args.input_cookie_file)
  File "/venv/lib/python3.10/site-packages/twspace_dl/login.py", line 9, in load_from_file
    return re.findall(
IndexError: list index out of range

User guide step by step for beginners

Hi,

I'm totally noob using this kind of softwares and I would like to request a step by step user guide for to download a Twitter Space.

Kind regards,

local variable 'twspace_dl' referenced before assignment

Describe the bug
https://github.com/Ryu1845/twspace-dl/blob/1ca12aa975c40c5d9020709e22332b041b2f13ef/twspace_dl/__main__.py#L173-L176

To Reproduce
twspace_dl -f https://prod-fastly-ap-northeast-1.video.pscp.tv/Transcoding/v1/hls/YRSsw6_P5xUZHMualK5-ihvePR6o4QmoZVOBGicKvmkL_KB9IQYtxVqm3P_vpZ2HnFkoRfar4_uJOjqC8OCo5A/non_transcode/ap-northeast-1/periscope-replay-direct-prod-ap-northeast-1-public/audio-space/master_playlist.m3u8

Expected behavior
use the master url for the processes(useful for ended spaces)

Output
If applicable, add the output of the command to help explain your problem.

Traceback (most recent call last):
  File "c:\users\test01\appdata\local\programs\python\python39\lib\runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "c:\users\test01\appdata\local\programs\python\python39\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "C:\Users\test01\AppData\Local\Programs\Python\Python39\Scripts\twspace_dl.exe\__main__.py", line 7, in <module>
  File "c:\users\test01\appdata\local\programs\python\python39\lib\site-packages\twspace_dl\__main__.py", line 116, in main
    args.func(args)
  File "c:\users\test01\appdata\local\programs\python\python39\lib\site-packages\twspace_dl\__main__.py", line 176, in twspace
    twspace_dl.master_url = args.from_master_url
UnboundLocalError: local variable 'twspace_dl' referenced before assignment

Desktop (please complete the following information):

  • OS: Windows
  • Version 2022.1.13.0
  • Installation method pip

Additional context
Same problem in twspace_dl -d DYN_URL

Support Python 3.10

Is your feature request related to a problem? Please describe.
Currently the tool doesn’t work properly on Python 3.10. For example, the following command gives a "Space Ended" error (which is a red herring):

$ python --version
Python 3.10.2
$ twspace_dl -i https://twitter.com/i/spaces/1ypJdEAQvayxW
ERROR:root:Can't Download. Space has ended, can't retrieve master url. You can provide it with -f URL if you have it.
Traceback (most recent call last):
  File "/home/ige/.local/bin/twspace_dl", line 8, in <module>
    sys.exit(main())
  File "/home/ige/.local/lib/python3.10/site-packages/twspace_dl/__main__.py", line 145, in main
    twspace_dl.download()
  File "/home/ige/.local/lib/python3.10/site-packages/twspace_dl/TwspaceDL.py", line 226, in download
    self.write_playlist(save_dir=tempdir)
  File "/home/ige/.local/lib/python3.10/site-packages/twspace_dl/TwspaceDL.py", line 217, in write_playlist
    stream_io.write(self.playlist_text)
  File "/home/ige/.local/lib/python3.10/site-packages/twspace_dl/TwspaceDL.py", line 207, in playlist_text
    playlist_text = requests.get(self.playlist_url).text
  File "/home/ige/.local/lib/python3.10/site-packages/twspace_dl/TwspaceDL.py", line 198, in playlist_url
    response = requests.get(self.master_url)
  File "/usr/lib64/python3.10/functools.py", line 981, in __get__
    val = self.func(instance)
  File "/home/ige/.local/lib/python3.10/site-packages/twspace_dl/TwspaceDL.py", line 190, in master_url
    master_url = self.dyn_url.replace(
  File "/usr/lib64/python3.10/functools.py", line 981, in __get__
    val = self.func(instance)
  File "/home/ige/.local/lib/python3.10/site-packages/twspace_dl/TwspaceDL.py", line 166, in dyn_url
    raise ValueError("Space Ended")
ValueError: Space Ended

While the same command on Python 3.9 starts downloading the stream:

$ python --version
Python 3.9.9
$ twspace_dl -i https://twitter.com/i/spaces/1ypJdEAQvayxW
INFO:root:./tmpel3_ukv3/(Sandy Hudson)Sandy & Nora Talk...What Now?-1ypJdEAQvayxW.m3u8Β written to disk

I don’t know where exactly the problem lies, but I know other packages/tools had problems running on Python 3.10 as well (before they specifically added support for it).

Describe the solution you'd like
The tool should support Python 3.10.

Describe alternatives you've considered
I can use the tool via a Python 3.9 virtual environment for now, but I would prefer to use my system’s default Python installation.

Additional context
β€”

request

"Changing ID3 metadata in HLS audio elementary stream is not implemented. Update your FFmpeg "....

release with ffmeg file please another time.

thank you.

Accept input metadata

The space metadata endpoint only returns up to 30d, the script already has an output option using the output file as input shouldn't be too much trouble

Add user ID format specifier

Is your feature request related to a problem? Please describe.
People can change their Twitter handle/username whenever, I'd prefer to use the immutable user ID (for example 44196397)

Describe the solution you'd like
Add %(creator_id)s

Twitter spaces api

Hi, I have worked on these download jobs before.
I would suggest using this one instead of user_tweet
https://twitter.com/i/api/fleets/v1/avatar_content?user_ids={userIds}&only_spaces=true
as I have met some people does not share the spaces to tweet.
This method allows multi-user.

The only problem is it may be connection aborted.


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/Command/spaces2.py", line 85, in <module>
    lives = fleetAvatar(idList, authHeaders)
  File "/home/Command/spaces2.py", line 39, in fleetAvatar
    rep = s.get(f'https://twitter.com/i/api/fleets/v1/avatar_content?user_ids={userIds}&only_spaces=true', headers=headers)
  File "/home/.local/lib/python3.8/site-packages/requests/sessions.py", line 555, in get
    return self.request('GET', url, **kwargs)
  File "/home/.local/lib/python3.8/site-packages/requests/sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "/home/.local/lib/python3.8/site-packages/requests/sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "/home/.local/lib/python3.8/site-packages/requests/adapters.py", line 498, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))```

Thank you to the contributors

Didn't see a "Thank you" issue so I'm creating this one so myself and others can express gratitude towards your amazing work.

Thanks for building this downloader and making it available for everyone!

I just bought you a coffee on Ko-fi, too.

That's all :)

Feel free to close this issue whenever.

Changing ID3 metadata in HLS audio elementary stream is not implemented....

Describe the bug
(A clear and concise description of what the bug is)

The lovely software claims there is a problem with ffmpeg:

Changing ID3 metadata in HLS audio elementary stream is not implemented. Update your FFmpeg version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented.

I then updated to the newest version:
ffmpeg version 4.4.1-0ubuntu1~20.04.sav0 Copyright (c) 2000-2021 the FFmpeg developers

It still throws the same message.

I'm at a loss.
(but it works fine it seems, it is downloading and all)

To Reproduce
command you entered
Freshly cloned from github.
twspace_dl -i https://twitter.com/i/spaces/1yNGaYwkkwRGj/peek --keep-files --output "spaces_1" --write-metadata --write-playlist --url --verbose

Expected behavior
A clear and concise description of what you expected to happen.

No yellow warning/error.

Output
If applicable, add the output of the command to help explain your problem.

Here is the start of the output. Maybe it gives some clues?

DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.twitter.com:443 DEBUG:urllib3.connectionpool:https://api.twitter.com:443 "POST /1.1/guest/activate.json HTTP/1.1" 200 63 DEBUG:root:1483188601676513280 DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): twitter.com:443 DEBUG:urllib3.connectionpool:https://twitter.com:443 "GET /i/api/graphql/jyQ0_DEMZHeoluCgHJ-U5Q/AudioSpaceById?variables=%7B%22id%22%3A%221yNGaYwkkwRGj%22%2C%22isMetatagsQuery%22%3Afalse%2C%22withSuperFollowsUserFields%22%3Atrue%2C%22withUserResults%22%3Atrue%2C%22withBirdwatchPivots%22%3Afalse%2C%22withReactionsMetadata%22%3Afalse%2C%22withReactionsPerspective%22%3Afalse%2C%22withSuperFollowsTweetFields%22%3Atrue%2C%22withReplays%22%3Atrue%2C%22withScheduledSpaces%22%3Atrue%7D HTTP/1.1" 200 16727 DEBUG:root:28_1482437358410612739 DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): twitter.com:443 DEBUG:urllib3.connectionpool:https://twitter.com:443 "GET /i/api/1.1/live_video_stream/status/28_1482437358410612739 HTTP/1.1" 200 1498 https://prod-fastly-us-east-1.video.pscp.tv/Transcoding/v1/hls/OK89FmpHuOx-NWTtW2D55Oo1PpwD2TI7I7N6VhO6ZWmbt_VB1AFfhmFeoYzeOHoC4AKVy2GtBLlEb_D29Ja9XQ/non_transcode/us-east-1/periscope-replay-direct-prod-us-east-1-public/audio-space/master_playlist.m3u8

Desktop (please complete the following information):

  • OS: [e.g. Windows] = Ubuntu 20.04
  • Version [e.g. 2021.12.10.1] =
  • Installation method (binary, pip, or other)

NAME="Ubuntu"
VERSION="20.04.3 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.3 LTS"
VERSION_ID="20.04"

  • Installation method: Cloned respiratory, 15 Jan, 2022
  • running it in conda envirnoment with python 3.9

Additional context
Add any other context about the problem here.

Unhandled `JSONDecodeError` when Twitter API returns 429

Describe the bug
I have setup a systemd service to monitor the start of Twitter spaces, and the time interval of running the command is 20 seconds. I do have multiple services monitoring multiple accounts, so it's normal to see some 429 Too Many Requests returned from the Twitter API. However, the response content didn't seem to be valid JSON (likely HTML), and it would cause a JSONDecodeError to be raised.

To Reproduce

twspace_dl --input-cookie-file "$twitter_cookies" -suU "https://twitter.com/$username" -o '/tmp/twspace_dl-%(creator_screen_name)s' -m -v

Expected behavior
It's not a big issue, but I think it would be better if this can be handled properly. Maybe retry after a timeout, or a better error message?

Output (Note: username and user ID are replaced by placeholders in the following log output)

2022-06-20 09:02:39,132 [DEBUG] Starting new HTTPS connection (1): cdn.syndication.twimg.com:443
2022-06-20 09:02:39,148 [DEBUG] https://cdn.syndication.twimg.com:443 "GET /widgets/followbutton/info.json?screen_names=<username> HTTP/1.1" 200 178
2022-06-20 09:02:39,149 [DEBUG] Starting new HTTPS connection (1): twitter.com:443
2022-06-20 09:02:39,360 [DEBUG] https://twitter.com:443 "GET /i/api/fleets/v1/avatar_content?user_ids=<user_id>&only_spaces=true HTTP/1.1" 429 0
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/dist-packages/requests/models.py", line 910, in json
    return complexjson.loads(self.text, **kwargs)
  File "/usr/lib/python3/dist-packages/simplejson/__init__.py", line 525, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3/dist-packages/simplejson/decoder.py", line 370, in decode
    obj, end = self.raw_decode(s)
  File "/usr/lib/python3/dist-packages/simplejson/decoder.py", line 400, in raw_decode
    return self.scan_once(s, idx=_w(s, idx).end())
simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/bin/twspace_dl", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.9/dist-packages/twspace_dl/__main__.py", line 199, in main
    args.func(args)
  File "/usr/local/lib/python3.9/dist-packages/twspace_dl/__main__.py", line 63, in space
    twspace = Twspace.from_user_avatar(args.user_url, auth_token)
  File "/usr/local/lib/python3.9/dist-packages/twspace_dl/twspace.py", line 231, in from_user_avatar
    avatar_content = requests.get(
  File "/usr/local/lib/python3.9/dist-packages/requests/models.py", line 917, in json
    raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: [Errno Expecting value] : 0

Desktop (please complete the following information):

  • OS: Linux
  • Version: Ubuntu 21.10
  • Installation method: pip

Better Exception handling / error print when trying to download a space that hasn't started

Is your feature request related to a problem? Please describe.

When trying to download a scheduled (but not start yet) space, it shows the following error:

>twspace_dl -i "https://twitter.com/i/spaces/1OdJrBeDpVkJX"
Traceback (most recent call last):
  File "C:\PROGRA~1\Python3\lib\runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\PROGRA~1\Python3\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "C:\PROGRA~1\Python3\Scripts\twspace_dl.exe\__main__.py", line 7, in <module>
  File "C:\PROGRA~1\Python3\lib\site-packages\twspace_dl\__main__.py", line 113, in main
    args.func(args)
  File "C:\PROGRA~1\Python3\lib\site-packages\twspace_dl\__main__.py", line 153, in space
    twspace = Twspace.from_space_url(args.input_url)
  File "C:\PROGRA~1\Python3\lib\site-packages\twspace_dl\twspace.py", line 165, in from_space_url
    return cls(cls._metadata(space_id))
  File "C:\PROGRA~1\Python3\lib\site-packages\twspace_dl\twspace.py", line 45, in __init__
    int(root["started_at"]) / 1000
ValueError: invalid literal for int() with base 10: ''

(because root["started_at"] would be '')

which is pretty vague. I wish it would just say "the stream hasn't started" or something like that.

Getting URL to play Directly

Is it possible to get URL to play directly on media player?

Master URL doesn't play on MPV but from Twitter, I get recorded space's URLs like below and it plays fine:

https://prod-fastly-eu-central-1.video.pscp.tv/Transcoding/v1/hls/*****/non_transcode/eu-central-1/periscope-replay-direct-prod-eu-central-1-public/audio-space/playlist_16785278960880547822.m3u8?type=replay

Is there a way to convert/change master URLs like below to similar one above so we can play it with media player without downloading.

https://prod-fastly-eu-central-1.video.pscp.tv/Transcoding/v1/hls/*****/non_transcode/eu-central-1/periscope-replay-direct-prod-eu-central-1-public/audio-space/master_playlist.m3u8

Only missing thing is this:
playlist_16785278960880547822

I couldn't find this part in metadata.json file.

subprocess.CalledProcessError

Describe the bug
When I use the twspace_dl tool in the linux enviroment, I encountered the subprocess.CalledProcessError, the detailed errors are displayed as follows:

To Reproduce
Input command example : twspace_dl -i https://twitter.com/i/spaces/1eaKbNOMMmXKX

Output
Error Output:

Unrecognized option 'protocol_whitelist'.
Error splitting the argument list: Option not found
Traceback (most recent call last):
File "/root/anaconda3/lib/python3.8/site-packages/twspace_dl/twspace_dl.py", line 164, in download
subprocess.run(cmd_old, check=True)
File "/root/anaconda3/lib/python3.8/subprocess.py", line 512, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['ffmpeg', '-protocol_whitelist', 'file,https,tls,tcp', '-y', '-stats', '-v', 'warning', '-i', './tmpur8x10cr/............................', '-c', 'copy', '-metadata', 'title=......', '-metadata', 'artist=................', '-metadata', 'episode_id=1BdGYwOazmgxX', './tmpur8x10cr/.........']' returned non-zero exit status 1.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/root/anaconda3/bin/twspace_dl", line 8, in
sys.exit(main())
File "/root/anaconda3/lib/python3.8/site-packages/twspace_dl/main.py", line 199, in main
args.func(args)
File "/root/anaconda3/lib/python3.8/site-packages/twspace_dl/main.py", line 92, in space
twspace_dl.download()
File "/root/anaconda3/lib/python3.8/site-packages/twspace_dl/twspace_dl.py", line 166, in download
raise RuntimeError(" ".join(err.cmd)) from err
RuntimeError: ffmpeg -protocol_whitelist file,https,tls,tcp -y -stats -v warning -i ./tmpur8x10cr/............ -c copy -metadata title=.......... -metadata artist=............... -metadata episode_id=1BdGYwOazmgxX ./tmpur8x10cr/............BdGYwOazmgxX.m4a

Desktop (please complete the following information):

  • OS: Linux
  • Installation method :pip install

requests.get(...)->urllib.request.urlopen(...)

To make more lighter and portable, it is better way to use urllib instead of requests.

Now:

import requests # 3rd party
res = requests.get(
  URL, headers=headers, params=params,
)
res.text # get source
res.json() # get dict from json-like source

TODO:

import json
from urllib.request import urlopen, Request # build-in
from urllib.parse import urlencode # build-in
r = Request(
  f"{URL}?{urlencode(params)}", headers=headers,
)
res = urlopen(r)
res.read()
json.loads(res.read().decode('utf-8'))

No guest token found after five retry

Describe the bug

Traceback (most recent call last):
File "/home/.local/bin/twspace_dl", line 8, in
sys.exit(main())
File "/home/.local/lib/python3.9/site-packages/twspace_dl/main.py", line 145, in main
twspace_dl.download()
File "/home/.local/lib/python3.9/site-packages/twspace_dl/TwspaceDL.py", line 224, in download
metadata = self.metadata
File "/usr/lib/python3.9/functools.py", line 969, in get
val = self.func(instance)
File "/home/.local/lib/python3.9/site-packages/twspace_dl/TwspaceDL.py", line 133, in metadata
"x-guest-token": self.guest_token(),
File "/home/.local/lib/python3.9/site-packages/twspace_dl/TwspaceDL.py", line 104, in guest_token
raise RuntimeError("No guest token found after five retry")
RuntimeError: No guest token found after five retry

To Reproduce
command you entered

Expected behavior
A clear and concise description of what you expected to happen.

Output
If applicable, add the output of the command to help explain your problem.

here

Desktop (please complete the following information):

  • OS: [e.g. Windows]
  • Version [e.g. 2021.12.10.1]
  • Installation method (binary, pip, or other)

Additional context
solution:

authConstant = 'Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA'

def auth():
headers = {'authorization': authConstant}
rep = s.post('https://api.twitter.com/1.1/guest/activate.json', headers=headers)
return {'authorization': authConstant, 'x-guest-token': rep.json()['guest_token']}, time.time()

Logging in with Twitter account without 2FA does not work

Describe the bug
Attempting to login with a twitter account which does not have 2FA enabled (but does get marked with an account duplication check request) will still ask for a 2FA code (which is impossible to get for an account without 2FA).

To Reproduce
twspace_dl --username USER --password PASSWORD -i SPACE_URL --output-cookie-file cookies.txt

Expected behavior
To be able to login to a twitter account without 2FA and generate a cookie file to use in later downloads.

Desktop (please complete the following information):

  • OS: Ubuntu 20.04.3 LTS (WSL2)
  • Version 2022.02.13
  • Installation method: pip

Override login when cookie files are not expired

Is your feature request related to a problem? Please describe.
About login / cookie

Describe the solution you'd like
Check the cookie is expired, and if the cookie is not expired, not login

Additional context

twspace_dl.py -U https://twitter.com/[user] --input-cookie-file cookie.txt login -u [username] -p [password] -o cookie.txt

When I run script like this, twspace-dl only gets a cookie, and not download twitter space. As I reffered #27, we need to check cookie file first, and it exists and not expired, skip login and trying to get and download twitter space.

This method will be better when run as Docker or Service (We can run as only one commands).

Temporary error "Invalid data found when processing input"

Describe the bug
On a Twitter space that recently ended, saw this error for some minutes. Retrying the same download again a bit later worked fine. Maybe just a transient Twitter issue with the data they provided for a recently ended space, and not something twspace-dl needs to worry about.

To Reproduce
Tried to download a recently ended space (ended a few minutes prior):

$ twspace_dl -m -i https://twitter.com/i/spaces/1DXxyDqgdbNJM?s=20

Expected behavior
Download the space successfully

Output

./tmppau4qu6q/(Mriya Report)MriyaReport - Russian Invasion of πŸ‡ΊπŸ‡¦ Crimea Actions ⛑️ via MriyaAid.org-1DXxyDqgdbNJM.m3u8: Invalid data found when processing input
Error: ffmpeg -protocol_whitelist file,https,tls,tcp -y -stats -v warning -i ./tmppau4qu6q/(Mriya Report)MriyaReport - Russian Invasion of πŸ‡ΊπŸ‡¦ Crimea Actions ⛑️ via MriyaAid.org-1DXxyDqgdbNJM.m3u8 -c copy -metadata title=MriyaReport - Russian Invasion of πŸ‡ΊπŸ‡¦ Crimea Actions ⛑️ via MriyaAid.org -metadata artist=Mriya Report -metadata episode_id=1DXxyDqgdbNJM ./tmppau4qu6q/(Mriya Report)MriyaReport - Russian Invasion of πŸ‡ΊπŸ‡¦ Crimea Actions ⛑️ via MriyaAid.org-1DXxyDqgdbNJM.m4a
Retry with -v to see more details
[eduardr@lion ~/Desktop/2022-08-10_1]$  twspace_dl -m -v -i https://twitter.com/i/spaces/1DXxyDqgdbNJM?s=20
2022-08-10 11:55:37,119 [DEBUG] Starting new HTTPS connection (1): api.twitter.com:443
2022-08-10 11:55:37,208 [DEBUG] https://api.twitter.com:443 "POST /1.1/guest/activate.json HTTP/1.1" 200 63
2022-08-10 11:55:37,213 [DEBUG] Starting new HTTPS connection (1): twitter.com:443
2022-08-10 11:55:37,473 [DEBUG] https://twitter.com:443 "GET /i/api/graphql/jyQ0_DEMZHeoluCgHJ-U5Q/AudioSpaceById?variables=%7B%22id%22%3A%221DXxyDqgdbNJM%22%2C%22isMetatagsQuery%22%3Afalse%2C%22withSuperFollowsUserFields%22%3Atrue%2C%22withUserResults%22%3Atrue%2C%22withBirdwatchPivots%22%3Afalse%2C%22withReactionsMetadata%22%3Afalse%2C%22withReactionsPerspective%22%3Afalse%2C%22withSuperFollowsTweetFields%22%3Atrue%2C%22withReplays%22%3Atrue%2C%22withScheduledSpaces%22%3Atrue%7D HTTP/1.1" 200 8031
2022-08-10 11:55:37,476 [DEBUG] Media Key: 28_1557383083459952641
2022-08-10 11:55:37,480 [DEBUG] Starting new HTTPS connection (1): cdn.syndication.twimg.com:443
2022-08-10 11:55:37,549 [DEBUG] https://cdn.syndication.twimg.com:443 "GET /widgets/followbutton/info.json?screen_names=MriyaReport HTTP/1.1" 200 156
2022-08-10 11:55:37,559 [DEBUG] Starting new HTTPS connection (1): twitter.com:443
2022-08-10 11:55:37,769 [DEBUG] https://twitter.com:443 "GET /i/api/1.1/live_video_stream/status/28_1557383083459952641 HTTP/1.1" 200 1498
2022-08-10 11:55:37,775 [DEBUG] Starting new HTTPS connection (1): prod-fastly-eu-central-1.video.pscp.tv:443
2022-08-10 11:55:38,020 [DEBUG] https://prod-fastly-eu-central-1.video.pscp.tv:443 "GET /Transcoding/v1/hls/zEg3Tz98sqlLU67tjex73hlyWdJsIfdcR11UO7Dj41CTBXT_Wsma_HszidusGs0qbpeGcwyJvswODSeDyJcmTQ/non_transcode/eu-central-1/periscope-replay-direct-prod-eu-central-1-public/audio-space/master_playlist.m3u8 HTTP/1.1" 200 550
2022-08-10 11:55:38,025 [DEBUG] Starting new HTTPS connection (1): prod-fastly-eu-central-1.video.pscp.tv:443
2022-08-10 11:55:38,282 [DEBUG] https://prod-fastly-eu-central-1.video.pscp.tv:443 "GET /Transcoding/v1/hls/zEg3Tz98sqlLU67tjex73hlyWdJsIfdcR11UO7Dj41CTBXT_Wsma_HszidusGs0qbpeGcwyJvswODSeDyJcmTQ/transcode/eu-central-1/periscope-replay-direct-prod-eu-central-1-public/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsInZlcnNpb24iOiIyIn0.eyJIZWlnaHQiOjgsIkticHMiOjM1MCwiVHJhbnNjb2RlQXVkaW8iOnRydWUsIldpZHRoIjo4fQ.j9A1sJbguxIY34C17U6iN7yTx8JM_ZNYJhfxaSmwGKQ/audio-space/playlist_16786592591867834374.m3u8 HTTP/1.1" 404 10
2022-08-10 11:55:38,285 [DEBUG] ./tmp0d075lpp/(Mriya Report)MriyaReport - Russian Invasion of πŸ‡ΊπŸ‡¦ Crimea Actions ⛑️ via MriyaAid.org-1DXxyDqgdbNJM.m3u8 written to disk
2022-08-10 11:55:38,285 [DEBUG] Command for the old part: ffmpeg -protocol_whitelist file,https,tls,tcp -y -stats -v warning -i ./tmp0d075lpp/(Mriya Report)MriyaReport - Russian Invasion of πŸ‡ΊπŸ‡¦ Crimea Actions ⛑️ via MriyaAid.org-1DXxyDqgdbNJM.m3u8 -c copy -metadata title=MriyaReport - Russian Invasion of πŸ‡ΊπŸ‡¦ Crimea Actions ⛑️ via MriyaAid.org -metadata artist=Mriya Report -metadata episode_id=1DXxyDqgdbNJM ./tmp0d075lpp/(Mriya Report)MriyaReport - Russian Invasion of πŸ‡ΊπŸ‡¦ Crimea Actions ⛑️ via MriyaAid.org-1DXxyDqgdbNJM.m4a
./tmp0d075lpp/(Mriya Report)MriyaReport - Russian Invasion of πŸ‡ΊπŸ‡¦ Crimea Actions ⛑️ via MriyaAid.org-1DXxyDqgdbNJM.m3u8: Invalid data found when processing input
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/twspace_dl/twspace_dl.py", line 171, in download
    subprocess.run(cmd_old, check=True)
  File "/usr/local/Cellar/[email protected]/3.9.13_2/Frameworks/Python.framework/Versions/3.9/lib/python3.9/subprocess.py", line 528, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['ffmpeg', '-protocol_whitelist', 'file,https,tls,tcp', '-y', '-stats', '-v', 'warning', '-i', './tmp0d075lpp/(Mriya Report)MriyaReport - Russian Invasion of πŸ‡ΊπŸ‡¦ Crimea Actions ⛑️ via MriyaAid.org-1DXxyDqgdbNJM.m3u8', '-c', 'copy', '-metadata', 'title=MriyaReport - Russian Invasion of πŸ‡ΊπŸ‡¦ Crimea Actions ⛑️ via MriyaAid.org', '-metadata', 'artist=Mriya Report', '-metadata', 'episode_id=1DXxyDqgdbNJM', './tmp0d075lpp/(Mriya Report)MriyaReport - Russian Invasion of πŸ‡ΊπŸ‡¦ Crimea Actions ⛑️ via MriyaAid.org-1DXxyDqgdbNJM.m4a']' returned non-zero exit status 1.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/bin/twspace_dl", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.9/site-packages/twspace_dl/__main__.py", line 231, in main
    args.func(args)
  File "/usr/local/lib/python3.9/site-packages/twspace_dl/__main__.py", line 123, in space
    twspace_dl.download()
  File "/usr/local/lib/python3.9/site-packages/twspace_dl/twspace_dl.py", line 173, in download
    raise RuntimeError(" ".join(err.cmd)) from err
RuntimeError: ffmpeg -protocol_whitelist file,https,tls,tcp -y -stats -v warning -i ./tmp0d075lpp/(Mriya Report)MriyaReport - Russian Invasion of πŸ‡ΊπŸ‡¦ Crimea Actions ⛑️ via MriyaAid.org-1DXxyDqgdbNJM.m3u8 -c copy -metadata title=MriyaReport - Russian Invasion of πŸ‡ΊπŸ‡¦ Crimea Actions ⛑️ via MriyaAid.org -metadata artist=Mriya Report -metadata episode_id=1DXxyDqgdbNJM ./tmp0d075lpp/(Mriya Report)MriyaReport - Russian Invasion of πŸ‡ΊπŸ‡¦ Crimea Actions ⛑️ via MriyaAid.org-1DXxyDqgdbNJM.m4a

Desktop (please complete the following information):

  • OS: MacOS 11.6.8 (20G730) (x86)
  • Version: 2022.6.6.1
  • Installation method: pip (python3)

Additional context
Workaround: wait some time and retry the same download. Appears to be a temporary Twitter issue with the data Twitter returns shortly after a space ends. Wait a few minutes or more and try the same download again, it should work.

Need timeout for requests

Describe the bug
Sometimes it freezes forever

To Reproduce
Basically while true wrapped twspace_dl -U xxx -v

Expected behavior
continuously working with output like

2022-09-12 18:57:55,702 [DEBUG] Starting new HTTPS connection (1): cdn.syndication.twimg.com:443                                                                             
2022-09-12 18:57:55,875 [DEBUG] https://cdn.syndication.twimg.com:443 "GET /widgets/followbutton/info.json?screen_names=<username> HTTP/1.1" 200 207                       
2022-09-12 18:57:55,878 [DEBUG] Starting new HTTPS connection (1): api.twitter.com:443                                                                                       
2022-09-12 18:57:55,981 [DEBUG] https://api.twitter.com:443 "POST /1.1/guest/activate.json HTTP/1.1" 200 63                                                                  
2022-09-12 18:57:55,986 [DEBUG] Starting new HTTPS connection (1): twitter.com:443                                                                                           
2022-09-12 18:57:57,235 [DEBUG] https://twitter.com:443 "GET /i/api/graphql/jpCmlX6UgnPEZJknGKbmZA/UserTweets?variables=<blahblah> HTTP/1.1" 200 15612                                                                         

Output
If applicable, add the output of the command to help explain your problem.

2022-09-12 18:59:59,259 [DEBUG] Starting new HTTPS connection (1): cdn.syndication.twimg.com:443                                                                             
2022-09-12 18:59:59,277 [DEBUG] https://cdn.syndication.twimg.com:443 "GET /widgets/followbutton/info.json?screen_names=<username> HTTP/1.1" 200 207
2022-09-12 18:59:59,281 [DEBUG] Starting new HTTPS connection (1): api.twitter.com:443                                                                                       
2022-09-12 18:59:59,379 [DEBUG] https://api.twitter.com:443 "POST /1.1/guest/activate.json HTTP/1.1" 200 63
2022-09-12 18:59:59,384 [DEBUG] Starting new HTTPS connection (1): twitter.com:443 

and freeze forever

Desktop (please complete the following information):

  • OS: Archlinux
  • Version 26e4bd0
  • Installation method from git source

Additional context
A simple timeout requests.get(url,timeout=10) will make it not freeze anymore. It will throw an exception instead. but it's fine since it's in a while true. A retry mechanism is preferred but not required.

Add login method to parse space links

Is your feature request related to a problem? Please describe.

It seems that some user's space links are not parsed from UserTweets API.

When the user streams twitter spaces, twspace still has RuntimeError User is not live.

Describe the solution you'd like

https://github.com/Ryu1845/twspace-dl/blob/704b51438ca14487a58264fd966b6877961ee8f0/twspace_dl/TwspaceDL.py#L37

Add a login (or cookie) method / parameters instead of using UserTweets APIs.

Additional context
When we are on login, we can get space links from https://twitter.com/i/api/fleets/v1/avatar_content.

Documentation for ffmpeg

Since this project requires ffmpeg, it is better to write it in README.md.
i, e)

## Requirements

ffmpeg

Option to not download same file twice

In situation when space ended but still available for replay, running twspace_dl -U more than once will result in .m4a file being downloaded again and replacing already existing one. If systemd unit with RestartSec=15 is used, new download will be started as soon as old one finishes the entire time space stays available.

Checking if file with given name already exists before starting download would prevent this from happening. yt-dlp also has --download-archive option, which maintains list of id of successful downloads and skips over them if called twice.

Resume feature would be great

Is your feature request related to a problem? Please describe.
A long-running DL stopped in the middle (for no obvious reason), had to kill it w CTRL-C, and running the DL again started from 0.

Describe the solution you'd like
Maintain a progress tracking file, and resume DL if the process is stopped and re-started.

Describe alternatives you've considered
No way currently to resume a partial download

Additional context
Don't know if resume would be possible for Twitter Spaces. There are some download apps such as Youtube DL/yt-dlp and aria2c that are able to resume.

Twspace no longer download space since the beginnin

To Reproduce
twspace_dl -i https://twitter.com/i/spaces/1zqKVBkkngmKB/

Output
Warning line
Changing ID3 metadata in HLS audio elementary stream is not implemented. Update your FFmpeg version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented.

Desktop (please complete the following information):

  • OS: Tried both on Windows 10 and Centos 7
  • Version [twspace-dl-2021.12.18.3]
  • Installation method: pip

Additional context
Updated last version of FFmpeg.

picture

Did twitter block it or it just a bug ?

Unable to get guest token, won't download twitter space

Describe the bug
Unable to get guest token after multiple tries.

To Reproduce
twspace_dl -i

Expected behavior
Grab guest token and start download of the twitter space

Output
If applicable, add the output of the command to help explain your problem.

Traceback (most recent call last):er:4
  File "C:\Users\Xanek\AppData\Local\Temp\ON66CE~1\__main__.py", line 142, in main
  File "C:\Users\Xanek\AppData\Local\Temp\ON66CE~1\twspace_dl\TwspaceDL.py", line 235, in download
  File "C:\Users\Xanek\AppData\Local\Temp\ON66CE~1\functools.py", line 969, in __get__
  File "C:\Users\Xanek\AppData\Local\Temp\ON66CE~1\twspace_dl\TwspaceDL.py", line 138, in metadata
  File "C:\Users\Xanek\AppData\Local\Temp\ON66CE~1\twspace_dl\TwspaceDL.py", line 108, in guest_token
RuntimeError: No guest token found after five retry

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Xanek\AppData\Local\Temp\ON66CE~1\__main__.py", line 151, in <module>
  File "C:\Users\Xanek\AppData\Local\Temp\ON66CE~1\__main__.py", line 146, in main
AttributeError: 'TwspaceDL' object has no attribute '_tmpdir'

Desktop (please complete the following information):

  • OS: [e.g. Windows] Windows 10
  • Version [e.g. 2021.12.10.1] 19043.1415
  • Installation method (binary, pip, or other) .exe

Additional context
Add any other context about the problem here.

bug: script fails if there is a tmp file in directory

Describe your issue

When I run the script in a folder with a file named tmp. The script fails with logs attached to this issue

Reproduction steps

  1. Follow setup steps like normal
  2. Before running the script, run touch tmp
  3. The script now crashes and does not download the space

Potential fixes

Tempfile or something equivalent

An exception will be thrown if DynamicURL or MasterURL is specified.

Describe the bug
An exception will be thrown if DynamicURL or MasterURL is specified.

To Reproduce
DynamicURL

$ twspace_dl -d 'https://prod-fastly-ap-northeast-1.video.pscp.tv/Transcoding/v1/hls/****/non_transcode/ap-northeast-1/periscope-replay-direct-prod-ap-northeast-1-public/audio-space/playlist_****.m3u8?type=replay'
Traceback (most recent call last):
  File "/opt/homebrew/bin/twspace_dl", line 8, in <module>
    sys.exit(main())
  File "/opt/homebrew/lib/python3.10/site-packages/twspace_dl/__main__.py", line 203, in main
    args.func(args)
  File "/opt/homebrew/lib/python3.10/site-packages/twspace_dl/__main__.py", line 72, in space
    twspace = Twspace.from_space_url(args.input_url)
  File "/opt/homebrew/lib/python3.10/site-packages/twspace_dl/twspace.py", line 169, in from_space_url
    space_id = re.findall(r"(?<=spaces/)\w*", url)[0]
  File "/opt/homebrew/Cellar/[email protected]/3.10.2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/re.py", line 240, in findall
    return _compile(pattern, flags).findall(string)
TypeError: expected string or bytes-like object

MasterURL

$ twspace_dl -f 'https://prod-fastly-ap-northeast-1.video.pscp.tv/Transcoding/v1/hls/****/non_transcode/ap-northeast-1/periscope-replay-direct-prod-ap-northeast-1-public/audio-space/master_playlist.m3u8'
Traceback (most recent call last):
  File "/opt/homebrew/bin/twspace_dl", line 8, in <module>
    sys.exit(main())
  File "/opt/homebrew/lib/python3.10/site-packages/twspace_dl/__main__.py", line 203, in main
    args.func(args)
  File "/opt/homebrew/lib/python3.10/site-packages/twspace_dl/__main__.py", line 72, in space
    twspace = Twspace.from_space_url(args.input_url)
  File "/opt/homebrew/lib/python3.10/site-packages/twspace_dl/twspace.py", line 169, in from_space_url
    space_id = re.findall(r"(?<=spaces/)\w*", url)[0]
  File "/opt/homebrew/Cellar/[email protected]/3.10.2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/re.py", line 240, in findall
    return _compile(pattern, flags).findall(string)
TypeError: expected string or bytes-like object

Expected behavior

Can be downloaded successfully by specifying DynamicURL or MasterURL.

Describe alternatives you've considered

Since this ability to specify DynamicURL and MasterURL does not appear to be used, I suggest that it be removed.
I will explain why I thought the function to specify them was not being used.

else:
twspace = Twspace.from_space_url(args.input_url)
twspace_dl = TwspaceDL(twspace, args.output)
if args.from_dynamic_url:
twspace_dl.dyn_url = args.from_dynamic_url
if args.from_master_url:
twspace_dl.master_url = args.from_master_url

Reading the source code, one can see that the TwspaceDL class is called before DynamicURL and MasterURL are checked.

@cached_property
def dyn_url(self) -> str:
"""Returns the dynamic url i.e. the url used by the browser"""
space = self.space
if space["state"] == "Ended" and not space["available_for_replay"]:
logging.error(
(
"Can't Download. Space has ended, can't retrieve master url. "
"You can provide it with -f URL if you have it."
)
)
raise ValueError("Space Ended")
headers = {
"authorization": (
"Bearer "
"AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs"
"=1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA"
),
"cookie": "auth_token=",
}
media_key = space["media_key"]
response = requests.get(
"https://twitter.com/i/api/1.1/live_video_stream/status/" + media_key,
headers=headers,
)
try:
metadata = response.json()
except Exception as err:
raise RuntimeError("Space isn't available", space.source) from err
dyn_url = metadata["source"]["location"]
return dyn_url
@cached_property
def master_url(self) -> str:
"""Master URL for a space"""
master_url = re.sub(
r"(?<=/audio-space/).*", "master_playlist.m3u8", self.dyn_url
)
return master_url

Also, twspace_dl.dyn_url and twspace_dl.master_url are cached_property, so setters cannot be created.

Desktop (please complete the following information):

  • OS: macOS
  • Version: 12.3
  • Installation method: Build with poetry.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.