Skip to content

Repository files navigation

Tslazer-lite

Twitter Space and Broadcast (pscp.tv) Downloader

IMPORTANT: Since Oct 2024, downloading from a Space/Broadcast ID without logging in is working again. But it is still recommended to use cookies to prevent limiting in future.

This is an almost-rewrite based on original Tslazer v1 (not the overhaul branch). The codebase is largely rewritten and refactored to be more readable and maintainable. The main goal is to make it easier to understand and modify the code.

Some significant changes:

  • It now always downloads the original non-transcoded chunks to get the best quality (especially for videos).
  • Added Support for downloading AES encrypted streams.
  • Filename format (and filename if using dyn_url directly) now has a sensible default. So you don't need to always specify it.
  • Changed filename format templating to use python's string formatting instead of custom templating. This allows for more flexibility. For example, you can now use {datetime:%y%m%d} to get the date in yymmdd format.
  • Added retry for all the requests.
  • When merging raw AACs (ADTS), it now uses binary concatenation instead of ffmpeg concat filter. This is to work around a bug in ffmpeg concat that causes the audio to be having wrong duration. See this thread I created on Reddit for more info. It will still be remuxed into MP4 by ffmpeg in the end.

Requirements

This program requires ffmpeg binary to work. Make sure you have one in your PATH.

Typical command examples

Supported InputsExampleNote
Space IDtslazer -s 1ZkJzbdvLgyJvIt is recommanded to use -c cookies.txt with it.
Broadcast IDtslazer -s 1mnxeAVmnYaxX --broadcastUse --broadcast to indicate it is a broadcast instead of a space.
Space/Broadcast URLtslazer -s "https://x.com/i/broadcasts/1mnxeAVmnYaxX"It will automatically detect if it is a space or broadcast.
Master/Dynamic URLtslazer -d "https://prod-fastly-ap-northeast-2.video.pscp.tv/Transcoding/....m3u8"Any master/dynamic m3u8 URL will work.
Space ID and Master/Dynamic URLtslazer -s {ID} -d "https://prod-fastly-ap-northeast-2.video.pscp.tv/Transcoding/....m3u8"You can use the combination of both for Spaces that are already ended. This way, metadata can be fetched from the Space ID.

Detailed Usage

usage: tslazer.py [-h] [--path PATH] [--keep] [--cookies COOKIES] [--threads THREADS] [--simulate] [--debug] [--space_id SPACE_ID] [--video] [--withchat]
[--filename-format FILENAME_FORMAT] [--dyn_url DYN_URL] [--filename FILENAME]
Download Twitter Spaces at lazer fast speeds!
options:
-h, --help show this help message and exit
--path PATH, -p PATH Path to download the space
--keep, -k Keep the temporary files
--cookies COOKIES, --cookie COOKIES, -c COOKIES
Twitter cookies.txt file (in Netscape format)
--threads THREADS, -t THREADS
Number of threads to use for downloading
--simulate, -S Simulate the download process
--debug Enable debug logging. Will be automatically enabled if --simulate is used
Downloading from a Space/Broadcast ID/URL:
--space_id SPACE_ID, -s SPACE_ID
Twitter Space/Broadcast ID or URL
--video, --broadcast, -v, -b
Assume type is broadcast (instead of space) when only the ID is given. It is auto inferred if the full URL is given.
--withchat Export the Twitter Space's Chat
--filename-format FILENAME_FORMAT, -f FILENAME_FORMAT
Filename Format Options:
{host_display_name} Host Display Name
{host_username} Host Username
{host_user_id} Host User ID
{space_title} Space/Broadcast Title
{space_id} Space/Broadcast ID
{datetime} Space/Broadcast Start Time (Local)
{datetimeutc} Space/Broadcast Start Time (UTC)
{type} Type of the livestream (space or broadcast)
Default: {datetime:%y%m%d} @{host_username} {space_title}-twitter-{type}-{space_id}
Downloading from a dynamic or master URL:
--dyn_url DYN_URL, -d DYN_URL
Twitter Space Master URL or Dynamic Playlist URL
--filename FILENAME, -o FILENAME
Filename for the Twitter Space (default: twitter_{type}_{current_time:%Y%m%d_%H%M%S})

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - fireattack/tslazer · GitHub
Skip to content

Repository files navigation

Tslazer-lite

Twitter Space and Broadcast (pscp.tv) Downloader

IMPORTANT: Since Oct 2024, downloading from a Space/Broadcast ID without logging in is working again. But it is still recommended to use cookies to prevent limiting in future.

This is an almost-rewrite based on original Tslazer v1 (not the overhaul branch). The codebase is largely rewritten and refactored to be more readable and maintainable. The main goal is to make it easier to understand and modify the code.

Some significant changes:

  • It now always downloads the original non-transcoded chunks to get the best quality (especially for videos).
  • Added Support for downloading AES encrypted streams.
  • Filename format (and filename if using dyn_url directly) now has a sensible default. So you don't need to always specify it.
  • Changed filename format templating to use python's string formatting instead of custom templating. This allows for more flexibility. For example, you can now use {datetime:%y%m%d} to get the date in yymmdd format.
  • Added retry for all the requests.
  • When merging raw AACs (ADTS), it now uses binary concatenation instead of ffmpeg concat filter. This is to work around a bug in ffmpeg concat that causes the audio to be having wrong duration. See this thread I created on Reddit for more info. It will still be remuxed into MP4 by ffmpeg in the end.

Requirements

This program requires ffmpeg binary to work. Make sure you have one in your PATH.

Typical command examples

Supported InputsExampleNote
Space IDtslazer -s 1ZkJzbdvLgyJvIt is recommanded to use -c cookies.txt with it.
Broadcast IDtslazer -s 1mnxeAVmnYaxX --broadcastUse --broadcast to indicate it is a broadcast instead of a space.
Space/Broadcast URLtslazer -s "https://x.com/i/broadcasts/1mnxeAVmnYaxX"It will automatically detect if it is a space or broadcast.
Master/Dynamic URLtslazer -d "https://prod-fastly-ap-northeast-2.video.pscp.tv/Transcoding/....m3u8"Any master/dynamic m3u8 URL will work.
Space ID and Master/Dynamic URLtslazer -s {ID} -d "https://prod-fastly-ap-northeast-2.video.pscp.tv/Transcoding/....m3u8"You can use the combination of both for Spaces that are already ended. This way, metadata can be fetched from the Space ID.

Detailed Usage

usage: tslazer.py [-h] [--path PATH] [--keep] [--cookies COOKIES] [--threads THREADS] [--simulate] [--debug] [--space_id SPACE_ID] [--video] [--withchat]
[--filename-format FILENAME_FORMAT] [--dyn_url DYN_URL] [--filename FILENAME]
Download Twitter Spaces at lazer fast speeds!
options:
-h, --help show this help message and exit
--path PATH, -p PATH Path to download the space
--keep, -k Keep the temporary files
--cookies COOKIES, --cookie COOKIES, -c COOKIES
Twitter cookies.txt file (in Netscape format)
--threads THREADS, -t THREADS
Number of threads to use for downloading
--simulate, -S Simulate the download process
--debug Enable debug logging. Will be automatically enabled if --simulate is used
Downloading from a Space/Broadcast ID/URL:
--space_id SPACE_ID, -s SPACE_ID
Twitter Space/Broadcast ID or URL
--video, --broadcast, -v, -b
Assume type is broadcast (instead of space) when only the ID is given. It is auto inferred if the full URL is given.
--withchat Export the Twitter Space's Chat
--filename-format FILENAME_FORMAT, -f FILENAME_FORMAT
Filename Format Options:
{host_display_name} Host Display Name
{host_username} Host Username
{host_user_id} Host User ID
{space_title} Space/Broadcast Title
{space_id} Space/Broadcast ID
{datetime} Space/Broadcast Start Time (Local)
{datetimeutc} Space/Broadcast Start Time (UTC)
{type} Type of the livestream (space or broadcast)
Default: {datetime:%y%m%d} @{host_username} {space_title}-twitter-{type}-{space_id}
Downloading from a dynamic or master URL:
--dyn_url DYN_URL, -d DYN_URL
Twitter Space Master URL or Dynamic Playlist URL
--filename FILENAME, -o FILENAME
Filename for the Twitter Space (default: twitter_{type}_{current_time:%Y%m%d_%H%M%S})

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - fireattack/tslazer · GitHub
Skip to content

Repository files navigation

Tslazer-lite

Twitter Space and Broadcast (pscp.tv) Downloader

IMPORTANT: Since Oct 2024, downloading from a Space/Broadcast ID without logging in is working again. But it is still recommended to use cookies to prevent limiting in future.

This is an almost-rewrite based on original Tslazer v1 (not the overhaul branch). The codebase is largely rewritten and refactored to be more readable and maintainable. The main goal is to make it easier to understand and modify the code.

Some significant changes:

  • It now always downloads the original non-transcoded chunks to get the best quality (especially for videos).
  • Added Support for downloading AES encrypted streams.
  • Filename format (and filename if using dyn_url directly) now has a sensible default. So you don't need to always specify it.
  • Changed filename format templating to use python's string formatting instead of custom templating. This allows for more flexibility. For example, you can now use {datetime:%y%m%d} to get the date in yymmdd format.
  • Added retry for all the requests.
  • When merging raw AACs (ADTS), it now uses binary concatenation instead of ffmpeg concat filter. This is to work around a bug in ffmpeg concat that causes the audio to be having wrong duration. See this thread I created on Reddit for more info. It will still be remuxed into MP4 by ffmpeg in the end.

Requirements

This program requires ffmpeg binary to work. Make sure you have one in your PATH.

Typical command examples

Supported InputsExampleNote
Space IDtslazer -s 1ZkJzbdvLgyJvIt is recommanded to use -c cookies.txt with it.
Broadcast IDtslazer -s 1mnxeAVmnYaxX --broadcastUse --broadcast to indicate it is a broadcast instead of a space.
Space/Broadcast URLtslazer -s "https://x.com/i/broadcasts/1mnxeAVmnYaxX"It will automatically detect if it is a space or broadcast.
Master/Dynamic URLtslazer -d "https://prod-fastly-ap-northeast-2.video.pscp.tv/Transcoding/....m3u8"Any master/dynamic m3u8 URL will work.
Space ID and Master/Dynamic URLtslazer -s {ID} -d "https://prod-fastly-ap-northeast-2.video.pscp.tv/Transcoding/....m3u8"You can use the combination of both for Spaces that are already ended. This way, metadata can be fetched from the Space ID.

Detailed Usage

usage: tslazer.py [-h] [--path PATH] [--keep] [--cookies COOKIES] [--threads THREADS] [--simulate] [--debug] [--space_id SPACE_ID] [--video] [--withchat]
[--filename-format FILENAME_FORMAT] [--dyn_url DYN_URL] [--filename FILENAME]
Download Twitter Spaces at lazer fast speeds!
options:
-h, --help show this help message and exit
--path PATH, -p PATH Path to download the space
--keep, -k Keep the temporary files
--cookies COOKIES, --cookie COOKIES, -c COOKIES
Twitter cookies.txt file (in Netscape format)
--threads THREADS, -t THREADS
Number of threads to use for downloading
--simulate, -S Simulate the download process
--debug Enable debug logging. Will be automatically enabled if --simulate is used
Downloading from a Space/Broadcast ID/URL:
--space_id SPACE_ID, -s SPACE_ID
Twitter Space/Broadcast ID or URL
--video, --broadcast, -v, -b
Assume type is broadcast (instead of space) when only the ID is given. It is auto inferred if the full URL is given.
--withchat Export the Twitter Space's Chat
--filename-format FILENAME_FORMAT, -f FILENAME_FORMAT
Filename Format Options:
{host_display_name} Host Display Name
{host_username} Host Username
{host_user_id} Host User ID
{space_title} Space/Broadcast Title
{space_id} Space/Broadcast ID
{datetime} Space/Broadcast Start Time (Local)
{datetimeutc} Space/Broadcast Start Time (UTC)
{type} Type of the livestream (space or broadcast)
Default: {datetime:%y%m%d} @{host_username} {space_title}-twitter-{type}-{space_id}
Downloading from a dynamic or master URL:
--dyn_url DYN_URL, -d DYN_URL
Twitter Space Master URL or Dynamic Playlist URL
--filename FILENAME, -o FILENAME
Filename for the Twitter Space (default: twitter_{type}_{current_time:%Y%m%d_%H%M%S})

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - fireattack/tslazer · GitHub
Skip to content

Repository files navigation

Tslazer-lite

Twitter Space and Broadcast (pscp.tv) Downloader

IMPORTANT: Since Oct 2024, downloading from a Space/Broadcast ID without logging in is working again. But it is still recommended to use cookies to prevent limiting in future.

This is an almost-rewrite based on original Tslazer v1 (not the overhaul branch). The codebase is largely rewritten and refactored to be more readable and maintainable. The main goal is to make it easier to understand and modify the code.

Some significant changes:

  • It now always downloads the original non-transcoded chunks to get the best quality (especially for videos).
  • Added Support for downloading AES encrypted streams.
  • Filename format (and filename if using dyn_url directly) now has a sensible default. So you don't need to always specify it.
  • Changed filename format templating to use python's string formatting instead of custom templating. This allows for more flexibility. For example, you can now use {datetime:%y%m%d} to get the date in yymmdd format.
  • Added retry for all the requests.
  • When merging raw AACs (ADTS), it now uses binary concatenation instead of ffmpeg concat filter. This is to work around a bug in ffmpeg concat that causes the audio to be having wrong duration. See this thread I created on Reddit for more info. It will still be remuxed into MP4 by ffmpeg in the end.

Requirements

This program requires ffmpeg binary to work. Make sure you have one in your PATH.

Typical command examples

Supported InputsExampleNote
Space IDtslazer -s 1ZkJzbdvLgyJvIt is recommanded to use -c cookies.txt with it.
Broadcast IDtslazer -s 1mnxeAVmnYaxX --broadcastUse --broadcast to indicate it is a broadcast instead of a space.
Space/Broadcast URLtslazer -s "https://x.com/i/broadcasts/1mnxeAVmnYaxX"It will automatically detect if it is a space or broadcast.
Master/Dynamic URLtslazer -d "https://prod-fastly-ap-northeast-2.video.pscp.tv/Transcoding/....m3u8"Any master/dynamic m3u8 URL will work.
Space ID and Master/Dynamic URLtslazer -s {ID} -d "https://prod-fastly-ap-northeast-2.video.pscp.tv/Transcoding/....m3u8"You can use the combination of both for Spaces that are already ended. This way, metadata can be fetched from the Space ID.

Detailed Usage

usage: tslazer.py [-h] [--path PATH] [--keep] [--cookies COOKIES] [--threads THREADS] [--simulate] [--debug] [--space_id SPACE_ID] [--video] [--withchat]
[--filename-format FILENAME_FORMAT] [--dyn_url DYN_URL] [--filename FILENAME]
Download Twitter Spaces at lazer fast speeds!
options:
-h, --help show this help message and exit
--path PATH, -p PATH Path to download the space
--keep, -k Keep the temporary files
--cookies COOKIES, --cookie COOKIES, -c COOKIES
Twitter cookies.txt file (in Netscape format)
--threads THREADS, -t THREADS
Number of threads to use for downloading
--simulate, -S Simulate the download process
--debug Enable debug logging. Will be automatically enabled if --simulate is used
Downloading from a Space/Broadcast ID/URL:
--space_id SPACE_ID, -s SPACE_ID
Twitter Space/Broadcast ID or URL
--video, --broadcast, -v, -b
Assume type is broadcast (instead of space) when only the ID is given. It is auto inferred if the full URL is given.
--withchat Export the Twitter Space's Chat
--filename-format FILENAME_FORMAT, -f FILENAME_FORMAT
Filename Format Options:
{host_display_name} Host Display Name
{host_username} Host Username
{host_user_id} Host User ID
{space_title} Space/Broadcast Title
{space_id} Space/Broadcast ID
{datetime} Space/Broadcast Start Time (Local)
{datetimeutc} Space/Broadcast Start Time (UTC)
{type} Type of the livestream (space or broadcast)
Default: {datetime:%y%m%d} @{host_username} {space_title}-twitter-{type}-{space_id}
Downloading from a dynamic or master URL:
--dyn_url DYN_URL, -d DYN_URL
Twitter Space Master URL or Dynamic Playlist URL
--filename FILENAME, -o FILENAME
Filename for the Twitter Space (default: twitter_{type}_{current_time:%Y%m%d_%H%M%S})

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - fireattack/tslazer · GitHub
Skip to content

Repository files navigation

Tslazer-lite

Twitter Space and Broadcast (pscp.tv) Downloader

IMPORTANT: Since Oct 2024, downloading from a Space/Broadcast ID without logging in is working again. But it is still recommended to use cookies to prevent limiting in future.

This is an almost-rewrite based on original Tslazer v1 (not the overhaul branch). The codebase is largely rewritten and refactored to be more readable and maintainable. The main goal is to make it easier to understand and modify the code.

Some significant changes:

  • It now always downloads the original non-transcoded chunks to get the best quality (especially for videos).
  • Added Support for downloading AES encrypted streams.
  • Filename format (and filename if using dyn_url directly) now has a sensible default. So you don't need to always specify it.
  • Changed filename format templating to use python's string formatting instead of custom templating. This allows for more flexibility. For example, you can now use {datetime:%y%m%d} to get the date in yymmdd format.
  • Added retry for all the requests.
  • When merging raw AACs (ADTS), it now uses binary concatenation instead of ffmpeg concat filter. This is to work around a bug in ffmpeg concat that causes the audio to be having wrong duration. See this thread I created on Reddit for more info. It will still be remuxed into MP4 by ffmpeg in the end.

Requirements

This program requires ffmpeg binary to work. Make sure you have one in your PATH.

Typical command examples

Supported InputsExampleNote
Space IDtslazer -s 1ZkJzbdvLgyJvIt is recommanded to use -c cookies.txt with it.
Broadcast IDtslazer -s 1mnxeAVmnYaxX --broadcastUse --broadcast to indicate it is a broadcast instead of a space.
Space/Broadcast URLtslazer -s "https://x.com/i/broadcasts/1mnxeAVmnYaxX"It will automatically detect if it is a space or broadcast.
Master/Dynamic URLtslazer -d "https://prod-fastly-ap-northeast-2.video.pscp.tv/Transcoding/....m3u8"Any master/dynamic m3u8 URL will work.
Space ID and Master/Dynamic URLtslazer -s {ID} -d "https://prod-fastly-ap-northeast-2.video.pscp.tv/Transcoding/....m3u8"You can use the combination of both for Spaces that are already ended. This way, metadata can be fetched from the Space ID.

Detailed Usage

usage: tslazer.py [-h] [--path PATH] [--keep] [--cookies COOKIES] [--threads THREADS] [--simulate] [--debug] [--space_id SPACE_ID] [--video] [--withchat]
[--filename-format FILENAME_FORMAT] [--dyn_url DYN_URL] [--filename FILENAME]
Download Twitter Spaces at lazer fast speeds!
options:
-h, --help show this help message and exit
--path PATH, -p PATH Path to download the space
--keep, -k Keep the temporary files
--cookies COOKIES, --cookie COOKIES, -c COOKIES
Twitter cookies.txt file (in Netscape format)
--threads THREADS, -t THREADS
Number of threads to use for downloading
--simulate, -S Simulate the download process
--debug Enable debug logging. Will be automatically enabled if --simulate is used
Downloading from a Space/Broadcast ID/URL:
--space_id SPACE_ID, -s SPACE_ID
Twitter Space/Broadcast ID or URL
--video, --broadcast, -v, -b
Assume type is broadcast (instead of space) when only the ID is given. It is auto inferred if the full URL is given.
--withchat Export the Twitter Space's Chat
--filename-format FILENAME_FORMAT, -f FILENAME_FORMAT
Filename Format Options:
{host_display_name} Host Display Name
{host_username} Host Username
{host_user_id} Host User ID
{space_title} Space/Broadcast Title
{space_id} Space/Broadcast ID
{datetime} Space/Broadcast Start Time (Local)
{datetimeutc} Space/Broadcast Start Time (UTC)
{type} Type of the livestream (space or broadcast)
Default: {datetime:%y%m%d} @{host_username} {space_title}-twitter-{type}-{space_id}
Downloading from a dynamic or master URL:
--dyn_url DYN_URL, -d DYN_URL
Twitter Space Master URL or Dynamic Playlist URL
--filename FILENAME, -o FILENAME
Filename for the Twitter Space (default: twitter_{type}_{current_time:%Y%m%d_%H%M%S})

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - fireattack/tslazer · GitHub
Skip to content

Repository files navigation

Tslazer-lite

Twitter Space and Broadcast (pscp.tv) Downloader

IMPORTANT: Since Oct 2024, downloading from a Space/Broadcast ID without logging in is working again. But it is still recommended to use cookies to prevent limiting in future.

This is an almost-rewrite based on original Tslazer v1 (not the overhaul branch). The codebase is largely rewritten and refactored to be more readable and maintainable. The main goal is to make it easier to understand and modify the code.

Some significant changes:

  • It now always downloads the original non-transcoded chunks to get the best quality (especially for videos).
  • Added Support for downloading AES encrypted streams.
  • Filename format (and filename if using dyn_url directly) now has a sensible default. So you don't need to always specify it.
  • Changed filename format templating to use python's string formatting instead of custom templating. This allows for more flexibility. For example, you can now use {datetime:%y%m%d} to get the date in yymmdd format.
  • Added retry for all the requests.
  • When merging raw AACs (ADTS), it now uses binary concatenation instead of ffmpeg concat filter. This is to work around a bug in ffmpeg concat that causes the audio to be having wrong duration. See this thread I created on Reddit for more info. It will still be remuxed into MP4 by ffmpeg in the end.

Requirements

This program requires ffmpeg binary to work. Make sure you have one in your PATH.

Typical command examples

Supported InputsExampleNote
Space IDtslazer -s 1ZkJzbdvLgyJvIt is recommanded to use -c cookies.txt with it.
Broadcast IDtslazer -s 1mnxeAVmnYaxX --broadcastUse --broadcast to indicate it is a broadcast instead of a space.
Space/Broadcast URLtslazer -s "https://x.com/i/broadcasts/1mnxeAVmnYaxX"It will automatically detect if it is a space or broadcast.
Master/Dynamic URLtslazer -d "https://prod-fastly-ap-northeast-2.video.pscp.tv/Transcoding/....m3u8"Any master/dynamic m3u8 URL will work.
Space ID and Master/Dynamic URLtslazer -s {ID} -d "https://prod-fastly-ap-northeast-2.video.pscp.tv/Transcoding/....m3u8"You can use the combination of both for Spaces that are already ended. This way, metadata can be fetched from the Space ID.

Detailed Usage

usage: tslazer.py [-h] [--path PATH] [--keep] [--cookies COOKIES] [--threads THREADS] [--simulate] [--debug] [--space_id SPACE_ID] [--video] [--withchat]
[--filename-format FILENAME_FORMAT] [--dyn_url DYN_URL] [--filename FILENAME]
Download Twitter Spaces at lazer fast speeds!
options:
-h, --help show this help message and exit
--path PATH, -p PATH Path to download the space
--keep, -k Keep the temporary files
--cookies COOKIES, --cookie COOKIES, -c COOKIES
Twitter cookies.txt file (in Netscape format)
--threads THREADS, -t THREADS
Number of threads to use for downloading
--simulate, -S Simulate the download process
--debug Enable debug logging. Will be automatically enabled if --simulate is used
Downloading from a Space/Broadcast ID/URL:
--space_id SPACE_ID, -s SPACE_ID
Twitter Space/Broadcast ID or URL
--video, --broadcast, -v, -b
Assume type is broadcast (instead of space) when only the ID is given. It is auto inferred if the full URL is given.
--withchat Export the Twitter Space's Chat
--filename-format FILENAME_FORMAT, -f FILENAME_FORMAT
Filename Format Options:
{host_display_name} Host Display Name
{host_username} Host Username
{host_user_id} Host User ID
{space_title} Space/Broadcast Title
{space_id} Space/Broadcast ID
{datetime} Space/Broadcast Start Time (Local)
{datetimeutc} Space/Broadcast Start Time (UTC)
{type} Type of the livestream (space or broadcast)
Default: {datetime:%y%m%d} @{host_username} {space_title}-twitter-{type}-{space_id}
Downloading from a dynamic or master URL:
--dyn_url DYN_URL, -d DYN_URL
Twitter Space Master URL or Dynamic Playlist URL
--filename FILENAME, -o FILENAME
Filename for the Twitter Space (default: twitter_{type}_{current_time:%Y%m%d_%H%M%S})

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - fireattack/tslazer · GitHub
Skip to content

Repository files navigation

Tslazer-lite

Twitter Space and Broadcast (pscp.tv) Downloader

IMPORTANT: Since Oct 2024, downloading from a Space/Broadcast ID without logging in is working again. But it is still recommended to use cookies to prevent limiting in future.

This is an almost-rewrite based on original Tslazer v1 (not the overhaul branch). The codebase is largely rewritten and refactored to be more readable and maintainable. The main goal is to make it easier to understand and modify the code.

Some significant changes:

  • It now always downloads the original non-transcoded chunks to get the best quality (especially for videos).
  • Added Support for downloading AES encrypted streams.
  • Filename format (and filename if using dyn_url directly) now has a sensible default. So you don't need to always specify it.
  • Changed filename format templating to use python's string formatting instead of custom templating. This allows for more flexibility. For example, you can now use {datetime:%y%m%d} to get the date in yymmdd format.
  • Added retry for all the requests.
  • When merging raw AACs (ADTS), it now uses binary concatenation instead of ffmpeg concat filter. This is to work around a bug in ffmpeg concat that causes the audio to be having wrong duration. See this thread I created on Reddit for more info. It will still be remuxed into MP4 by ffmpeg in the end.

Requirements

This program requires ffmpeg binary to work. Make sure you have one in your PATH.

Typical command examples

Supported InputsExampleNote
Space IDtslazer -s 1ZkJzbdvLgyJvIt is recommanded to use -c cookies.txt with it.
Broadcast IDtslazer -s 1mnxeAVmnYaxX --broadcastUse --broadcast to indicate it is a broadcast instead of a space.
Space/Broadcast URLtslazer -s "https://x.com/i/broadcasts/1mnxeAVmnYaxX"It will automatically detect if it is a space or broadcast.
Master/Dynamic URLtslazer -d "https://prod-fastly-ap-northeast-2.video.pscp.tv/Transcoding/....m3u8"Any master/dynamic m3u8 URL will work.
Space ID and Master/Dynamic URLtslazer -s {ID} -d "https://prod-fastly-ap-northeast-2.video.pscp.tv/Transcoding/....m3u8"You can use the combination of both for Spaces that are already ended. This way, metadata can be fetched from the Space ID.

Detailed Usage

usage: tslazer.py [-h] [--path PATH] [--keep] [--cookies COOKIES] [--threads THREADS] [--simulate] [--debug] [--space_id SPACE_ID] [--video] [--withchat]
[--filename-format FILENAME_FORMAT] [--dyn_url DYN_URL] [--filename FILENAME]
Download Twitter Spaces at lazer fast speeds!
options:
-h, --help show this help message and exit
--path PATH, -p PATH Path to download the space
--keep, -k Keep the temporary files
--cookies COOKIES, --cookie COOKIES, -c COOKIES
Twitter cookies.txt file (in Netscape format)
--threads THREADS, -t THREADS
Number of threads to use for downloading
--simulate, -S Simulate the download process
--debug Enable debug logging. Will be automatically enabled if --simulate is used
Downloading from a Space/Broadcast ID/URL:
--space_id SPACE_ID, -s SPACE_ID
Twitter Space/Broadcast ID or URL
--video, --broadcast, -v, -b
Assume type is broadcast (instead of space) when only the ID is given. It is auto inferred if the full URL is given.
--withchat Export the Twitter Space's Chat
--filename-format FILENAME_FORMAT, -f FILENAME_FORMAT
Filename Format Options:
{host_display_name} Host Display Name
{host_username} Host Username
{host_user_id} Host User ID
{space_title} Space/Broadcast Title
{space_id} Space/Broadcast ID
{datetime} Space/Broadcast Start Time (Local)
{datetimeutc} Space/Broadcast Start Time (UTC)
{type} Type of the livestream (space or broadcast)
Default: {datetime:%y%m%d} @{host_username} {space_title}-twitter-{type}-{space_id}
Downloading from a dynamic or master URL:
--dyn_url DYN_URL, -d DYN_URL
Twitter Space Master URL or Dynamic Playlist URL
--filename FILENAME, -o FILENAME
Filename for the Twitter Space (default: twitter_{type}_{current_time:%Y%m%d_%H%M%S})

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - fireattack/tslazer · GitHub
Skip to content

Repository files navigation

Tslazer-lite

Twitter Space and Broadcast (pscp.tv) Downloader

IMPORTANT: Since Oct 2024, downloading from a Space/Broadcast ID without logging in is working again. But it is still recommended to use cookies to prevent limiting in future.

This is an almost-rewrite based on original Tslazer v1 (not the overhaul branch). The codebase is largely rewritten and refactored to be more readable and maintainable. The main goal is to make it easier to understand and modify the code.

Some significant changes:

  • It now always downloads the original non-transcoded chunks to get the best quality (especially for videos).
  • Added Support for downloading AES encrypted streams.
  • Filename format (and filename if using dyn_url directly) now has a sensible default. So you don't need to always specify it.
  • Changed filename format templating to use python's string formatting instead of custom templating. This allows for more flexibility. For example, you can now use {datetime:%y%m%d} to get the date in yymmdd format.
  • Added retry for all the requests.
  • When merging raw AACs (ADTS), it now uses binary concatenation instead of ffmpeg concat filter. This is to work around a bug in ffmpeg concat that causes the audio to be having wrong duration. See this thread I created on Reddit for more info. It will still be remuxed into MP4 by ffmpeg in the end.

Requirements

This program requires ffmpeg binary to work. Make sure you have one in your PATH.

Typical command examples

Supported InputsExampleNote
Space IDtslazer -s 1ZkJzbdvLgyJvIt is recommanded to use -c cookies.txt with it.
Broadcast IDtslazer -s 1mnxeAVmnYaxX --broadcastUse --broadcast to indicate it is a broadcast instead of a space.
Space/Broadcast URLtslazer -s "https://x.com/i/broadcasts/1mnxeAVmnYaxX"It will automatically detect if it is a space or broadcast.
Master/Dynamic URLtslazer -d "https://prod-fastly-ap-northeast-2.video.pscp.tv/Transcoding/....m3u8"Any master/dynamic m3u8 URL will work.
Space ID and Master/Dynamic URLtslazer -s {ID} -d "https://prod-fastly-ap-northeast-2.video.pscp.tv/Transcoding/....m3u8"You can use the combination of both for Spaces that are already ended. This way, metadata can be fetched from the Space ID.

Detailed Usage

usage: tslazer.py [-h] [--path PATH] [--keep] [--cookies COOKIES] [--threads THREADS] [--simulate] [--debug] [--space_id SPACE_ID] [--video] [--withchat]
[--filename-format FILENAME_FORMAT] [--dyn_url DYN_URL] [--filename FILENAME]
Download Twitter Spaces at lazer fast speeds!
options:
-h, --help show this help message and exit
--path PATH, -p PATH Path to download the space
--keep, -k Keep the temporary files
--cookies COOKIES, --cookie COOKIES, -c COOKIES
Twitter cookies.txt file (in Netscape format)
--threads THREADS, -t THREADS
Number of threads to use for downloading
--simulate, -S Simulate the download process
--debug Enable debug logging. Will be automatically enabled if --simulate is used
Downloading from a Space/Broadcast ID/URL:
--space_id SPACE_ID, -s SPACE_ID
Twitter Space/Broadcast ID or URL
--video, --broadcast, -v, -b
Assume type is broadcast (instead of space) when only the ID is given. It is auto inferred if the full URL is given.
--withchat Export the Twitter Space's Chat
--filename-format FILENAME_FORMAT, -f FILENAME_FORMAT
Filename Format Options:
{host_display_name} Host Display Name
{host_username} Host Username
{host_user_id} Host User ID
{space_title} Space/Broadcast Title
{space_id} Space/Broadcast ID
{datetime} Space/Broadcast Start Time (Local)
{datetimeutc} Space/Broadcast Start Time (UTC)
{type} Type of the livestream (space or broadcast)
Default: {datetime:%y%m%d} @{host_username} {space_title}-twitter-{type}-{space_id}
Downloading from a dynamic or master URL:
--dyn_url DYN_URL, -d DYN_URL
Twitter Space Master URL or Dynamic Playlist URL
--filename FILENAME, -o FILENAME
Filename for the Twitter Space (default: twitter_{type}_{current_time:%Y%m%d_%H%M%S})

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages