Last active
January 19, 2025 16:44
-
-
Save cmj/c8b6964999029c3fdcf21da01a24ec3a to your computer and use it in GitHub Desktop.
Return live xSpaces audio feeds via search
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# playback live xSpaces audio feed | |
# archive HLS url if user disables playback feature | |
# source `auth_token` and `x_csrf_token` | |
source ~/.env-twitter | |
media_id=$1 | |
bearer_token='AAAAAAAAAAAAAAAAAAAAAFQODgEAAAAAVHTp76lzh3rFzcHbmHVvQxYYpTw%3DckAlMINMjmCwxUcaXbAN4XqJVdgMJaHqNOFgPMK0zN1qLqLQCF' | |
header=(-H "Authorization: Bearer ${bearer_token}" -H "User-Agent: TwitterAndroid/10.21.1" -H "X-Csrf-Token: ${x_csrf_token}" -H "Cookie: ct0=${x_csrf_token}; auth_token=${auth_token}") | |
url="https://x.com/i/api/1.1/live_video_stream/status/${media_id}" | |
stream=$(curl -s "${header[@]}" "${url}" | jq -r .source.noRedirectPlaybackUrl) | |
# archive the stream url for later use if host disables "replay" feature | |
#d=$(date -d '-1 day' +"%Y%m%d-%H%M%S") | |
#echo "${stream}" > "/home/cmj/dev/twitter/spaces/$id-$d.m3u8" | |
# mpv, vlc, mplayer | |
mpv --msg-level=ffmpeg=no "${stream}" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Spaces search - return list of Live audio feeds matching search query | |
# ./xSpacesLive football | |
# Use mpv, vlc, etc., to play streams | |
filter="Top" # [Live|Top] | |
limit=5 # limit results | |
# source x_csrf_token and auth_token | |
. ~/.env-twitter | |
query="$@" | |
#### | |
bearer_token='AAAAAAAAAAAAAAAAAAAAAFQODgEAAAAAVHTp76lzh3rFzcHbmHVvQxYYpTw%3DckAlMINMjmCwxUcaXbAN4XqJVdgMJaHqNOFgPMK0zN1qLqLQCF' | |
header=(-H "Authorization: Bearer ${bearer_token}" -H "User-Agent: TwitterAndroid/10.21.1" -H "X-Csrf-Token: ${x_csrf_token}" -H "Cookie: ct0=${x_csrf_token}; auth_token=${auth_token}") | |
url='https://x.com/i/api/graphql/NTq79TuSz6fHj8lQaferJw/AudioSpaceSearch' | |
variables='{"query":"'"${query}"'","filter":"'"${filter}"'"}' | |
features='{"creator_subscriptions_tweet_preview_api_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"articles_preview_enabled":true,"rweb_tipjar_consumption_enabled":true,"responsive_web_graphql_exclude_directive_enabled":true,"verified_phone_label_enabled":false,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":false,"creator_subscriptions_quote_tweet_preview_enabled":false,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"rweb_video_timestamps_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":false,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_enhance_cards_enabled":false}' | |
sp_url='https://x.com/i/api/graphql/p8k4kaPusjNj85gj8w_YAQ/AudioSpaceById' | |
sp_features='{"spaces_2022_h2_spaces_communities":true,"spaces_2022_h2_clipping":true,"creator_subscriptions_tweet_preview_api_enabled":true,"rweb_tipjar_consumption_enabled":true,"responsive_web_graphql_exclude_directive_enabled":true,"verified_phone_label_enabled":false,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"articles_preview_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":false,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":false,"creator_subscriptions_quote_tweet_preview_enabled":false,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"rweb_video_timestamps_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_enhance_cards_enabled":false}' | |
audio_url() { | |
media_id=$1 | |
url="https://x.com/i/api/1.1/live_video_stream/status/${media_id}" | |
curl -s "${header[@]}" "${url}" | jq -r .source.noRedirectPlaybackUrl | |
} | |
spaces() { | |
id=$1 | |
sp_variables='{"id":"'"${id}"'","isMetatagsQuery":false,"withReplays":true,"withListeners":true}' | |
space_by_id=$(curl -s -G "${header[@]}" "${sp_url}" \ | |
--data-urlencode "variables=${sp_variables}" \ | |
--data-urlencode "features=${sp_features}" ) | |
jq -r '.data.audioSpace | "\(.metadata.title) | Users: \(.participants.total) | Host: @\(.metadata.creator_results.result.legacy.screen_name) (\(.metadata.creator_results.result.legacy.name)) | Admins: \([.participants.admins[] | "@\(.twitter_screen_name)"] | join(" - ")) | Speakers: \([.participants.speakers[] | "@\(.twitter_screen_name)"] | join(" "))\nListeners: \([.participants.listeners[] | "@\(.twitter_screen_name)"] | join(" "))"' <<< "${space_by_id}" | |
media_key=$(jq -r .data.audioSpace.metadata.media_key <<< "${space_by_id}") | |
audio_url "${media_key}" | |
} | |
curl -s -G "${header[@]}" $url \ | |
--data-urlencode "variables=${variables}" \ | |
--data-urlencode "features=${features}" | | |
jq -r '.data.search_by_raw_query.audio_spaces_grouped_by_section | if(.sections[0].items[]) then .sections[0].items[].space.rest_id else empty end' | | |
head -$limit | | |
while read id; do | |
echo "# Space - $id" | |
spaces "${id}" | |
done # | ct # chromaterm |
Author
cmj
commented
Jan 19, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment