{"id":17670440,"url":"https://github.com/henrique-coder/streamsnapper","last_synced_at":"2025-12-26T20:57:38.100Z","repository":{"id":257800703,"uuid":"862673911","full_name":"henrique-coder/streamsnapper","owner":"henrique-coder","description":"StreamSnapper is an intuitive library designed to simplify, improve, and organize YouTube and Youtube Music media streams. It offers scraping functions with higher speed extraction and efficiency with the latest tools to perform such processes.","archived":false,"fork":false,"pushed_at":"2025-04-23T17:26:46.000Z","size":476,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-23T18:36:09.553Z","etag":null,"topics":["downloader","merger","scraper","snapper","stream","youtube"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/henrique-coder.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-09-25T02:05:58.000Z","updated_at":"2025-04-23T17:26:49.000Z","dependencies_parsed_at":"2024-10-30T22:32:21.770Z","dependency_job_id":"06bd5ba6-01db-464c-915a-4026b651c5ee","html_url":"https://github.com/henrique-coder/streamsnapper","commit_stats":{"total_commits":68,"total_committers":1,"mean_commits":68.0,"dds":0.0,"last_synced_commit":"53a19800f781f408b7c4497e8b2dc26be47d49e4"},"previous_names":["henrique-coder/streamsnapper"],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/henrique-coder%2Fstreamsnapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/henrique-coder%2Fstreamsnapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/henrique-coder%2Fstreamsnapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/henrique-coder%2Fstreamsnapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/henrique-coder","download_url":"https://codeload.github.com/henrique-coder/streamsnapper/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253179953,"owners_count":21866829,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["downloader","merger","scraper","snapper","stream","youtube"],"created_at":"2024-10-24T02:04:31.916Z","updated_at":"2025-12-26T20:57:38.093Z","avatar_url":"https://github.com/henrique-coder.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# StreamSnapper\n\n![PyPI - Version](https://img.shields.io/pypi/v/streamsnapper?style=for-the-badge\u0026logo=pypi\u0026logoColor=white\u0026color=0066cc)\n![PyPI - Downloads](https://img.shields.io/pypi/dm/streamsnapper?style=for-the-badge\u0026logo=pypi\u0026logoColor=white\u0026color=28a745)\n![Python Versions](https://img.shields.io/pypi/pyversions/streamsnapper?style=for-the-badge\u0026logo=python\u0026logoColor=white\u0026color=306998)\n![License](https://img.shields.io/pypi/l/streamsnapper?style=for-the-badge\u0026color=blue)\n\n**Extract and analyze YouTube video streams with intelligent quality selection and language fallback**\n\n[🚀 Quick Start](#-quick-start) • [📖 API Reference](#-api-reference) • [💡 Examples](#-examples)\n\n\u003c/div\u003e\n\n---\n\n## 🌟 Overview\n\nStreamSnapper extracts YouTube video/audio streams and metadata with intelligent filtering:\n\n- **Quality Selection** - Automatic fallback from preferred to available resolutions\n- **Language Priority** - Multi-language fallback with system locale detection\n- **Stream Filtering** - HDR, 4K, codec, bitrate, and format filtering\n- **Metadata Extraction** - Complete video information, chapters, and statistics\n\n## 🔧 Installation\n\n```bash\n# Stable release\nuv add --upgrade streamsnapper\n\n# Development version\nuv add --upgrade git+https://github.com/henrique-coder/streamsnapper.git --branch main\n```\n\n**Requirements:** Python 3.10+\n\n## 🚀 Quick Start\n\n### Basic Usage\n\n```python\nfrom streamsnapper import YouTube\n\n# Extract video data\nyt = YouTube()\nyt.extract(\"https://www.youtube.com/watch?v=dQw4w9WgXcQ\")\n\n# Analyze streams\nyt.analyze_information()\nyt.analyze_video_streams(\"1080p\", fallback=True)\nyt.analyze_audio_streams([\"pt-BR\", \"en-US\", \"source\"])\n\n# Access results\nprint(f\"Title: {yt.information.title}\")\nprint(f\"Best video: {yt.video_streams.best_stream.resolution}\")\nprint(f\"Best audio: {yt.audio_streams.best_stream.bitrate}kbps\")\n```\n\n### Quality Selection\n\n```python\n# Specific resolution with fallback\nyt.analyze_video_streams(\"1080p\", fallback=True)\n\n# Best or worst quality\nyt.analyze_video_streams(\"best\")\nyt.analyze_video_streams(\"worst\")\n\n# All streams for manual selection\nyt.analyze_video_streams(\"all\")\n```\n\n### Language Selection\n\n```python\n# Priority list (tries in order, fallback to source)\nyt.analyze_audio_streams([\"pt-BR\", \"en-US\", \"source\"])\n\n# System language (fallback to source)\nyt.analyze_audio_streams(\"local\")\n\n# Original audio (best quality)\nyt.analyze_audio_streams(\"source\")\n\n# All streams\nyt.analyze_audio_streams(\"all\")\n```\n\n### Private Content\n\n```python\nfrom streamsnapper import YouTube, SupportedCookieBrowser, CookieFile\n\n# Browser cookies\nyt = YouTube(cookies=SupportedCookieBrowser.CHROME)\n\n# Cookie file\nyt = YouTube(cookies=CookieFile(\"/path/to/cookies.txt\"))\n```\n\n## 💡 Examples\n\n### Filter Streams\n\n```python\n# Video filtering\nvideos = yt.video_streams\nhd_videos = videos.hd_streams              # ≥720p\nh264 = videos.get_by_codec(\"h264\")         # Specific codec\nhdr = videos.hdr_streams                   # HDR only\nuhd = videos.uhd_streams                   # 4K+\n\n# Audio filtering\naudios = yt.audio_streams\nhq_audio = audios.high_quality_streams     # ≥128kbps\nstereo = audios.stereo_streams             # 2 channels\npt_audio = audios.get_by_language(\"pt-BR\") # Language\n\n# Subtitle filtering\nsubs = yt.subtitle_streams\nmanual = subs.manual_subtitles             # Human-created\nen_subs = subs.get_by_language(\"en\")       # English\n```\n\n### Download Selection\n\n```python\n# Get best streams under size limit\nvideos = [v for v in yt.video_streams.streams if v.size_mb and v.size_mb \u003c= 100]\nbest_video = max(videos, key=lambda v: v.quality_score)\nbest_audio = yt.audio_streams.best_stream\n\nprint(f\"Video: {best_video.url}\")\nprint(f\"Audio: {best_audio.url}\")\n```\n\n### Batch Processing\n\n```python\ndef process_videos(urls: list[str]) -\u003e list[dict]:\n    results = []\n    for url in urls:\n        yt = YouTube()\n        yt.extract(url)\n        yt.analyze_information()\n        yt.analyze_video_streams(\"all\")\n\n        results.append({\n            'title': yt.information.title,\n            'duration': yt.information.duration_formatted,\n            'qualities': yt.video_streams.available_qualities,\n            'has_4k': len(yt.video_streams.uhd_streams) \u003e 0\n        })\n    return results\n```\n\n## 📖 API Reference\n\n### YouTube Class\n\n```python\nyt = YouTube(\n    logging=False,                # Enable debug logging\n    cookies=None                  # Browser or cookie file\n)\n\nyt.extract(url: str)              # Extract video data\n\nyt.analyze_information(\n    check_thumbnails=False,       # Validate thumbnail URLs\n    retrieve_dislike_count=False  # Fetch dislikes from API\n)\n\nyt.analyze_video_streams(\n    preferred_resolution=\"all\",   # \"720p\", \"1080p\", \"best\", \"worst\", \"all\"\n    fallback=True                 # Enable resolution fallback\n)\n\nyt.analyze_audio_streams(\n    preferred_language=\"all\"      # \"pt-BR\", [\"en-US\", \"source\"], \"local\", \"all\"\n)\n\nyt.analyze_subtitle_streams()     # Extract subtitle information\n```\n\n### VideoInformation\n\n```python\ninfo = yt.information\n\n# URLs\ninfo.short_url                    # youtu.be link\ninfo.embed_url                    # Embed URL\ninfo.full_url                     # Full watch URL\n\n# Metadata\ninfo.id                           # Video ID\ninfo.title                        # Title\ninfo.description                  # Description\ninfo.duration                     # Seconds\ninfo.duration_formatted           # HH:MM:SS\n\n# Channel\ninfo.channel_id                   # Channel ID\ninfo.channel_name                 # Channel name\ninfo.is_verified_channel          # Verification status\n\n# Statistics\ninfo.view_count                   # Views\ninfo.like_count                   # Likes\ninfo.comment_count                # Comments\ninfo.upload_date                  # Upload date\n\n# Additional\ninfo.categories                   # Categories list\ninfo.tags                         # Tags list\ninfo.thumbnails                   # Thumbnail URLs\ninfo.chapters                     # Chapter data\n```\n\n### VideoStream\n\n```python\nstream = yt.video_streams.best_stream\n\n# Quality\nstream.resolution                 # \"1080p\", \"720p\", etc\nstream.width                      # Width in pixels\nstream.height                     # Height in pixels\nstream.framerate                  # FPS\nstream.quality_score              # Ranking score\n\n# Format\nstream.codec                      # \"h264\", \"av1\", \"vp9\"\nstream.extension                  # \"mp4\", \"webm\"\nstream.bitrate                    # Bitrate\n\n# Flags\nstream.is_hd                      # ≥720p\nstream.is_full_hd                 # ≥1080p\nstream.is_4k                      # ≥2160p\nstream.is_hdr                     # HDR content\n\n# Download\nstream.url                        # Direct URL\nstream.size                       # Bytes\nstream.size_mb                    # Megabytes\n```\n\n### VideoStreamCollection\n\n```python\nvideos = yt.video_streams\n\n# Properties\nvideos.streams                    # All streams\nvideos.best_stream                # Highest quality\nvideos.worst_stream               # Lowest quality\nvideos.available_qualities        # [\"1080p\", \"720p\", ...]\nvideos.available_codecs           # [\"h264\", \"vp9\", ...]\n\n# Filters\nvideos.hd_streams                 # ≥720p\nvideos.full_hd_streams            # ≥1080p\nvideos.uhd_streams                # ≥2160p\nvideos.hdr_streams                # HDR only\n\n# Methods\nvideos.get_by_resolution(\"1080p\", fallback=True)\nvideos.get_by_codec(\"h264\")\nvideos.get_by_framerate_range(min_fps=60)\nvideos.get_by_size_range(max_mb=100)\n```\n\n### AudioStream\n\n```python\nstream = yt.audio_streams.best_stream\n\n# Quality\nstream.bitrate                    # Bitrate (kbps)\nstream.sample_rate                # Sample rate (Hz)\nstream.quality_score              # Ranking score\n\n# Format\nstream.codec                      # \"aac\", \"opus\"\nstream.extension                  # \"mp4\", \"webm\"\nstream.channels                   # Channel count\nstream.channel_description        # \"Stereo\", \"Surround 5.1\"\n\n# Language\nstream.language                   # Language code\nstream.language_name              # Language name\n\n# Flags\nstream.is_high_quality            # ≥128kbps\nstream.is_lossless_quality        # ≥320kbps \u0026 ≥48kHz\nstream.is_stereo                  # 2 channels\nstream.is_surround                # \u003e2 channels\n\n# Download\nstream.url                        # Direct URL\nstream.size                       # Bytes\nstream.size_mb                    # Megabytes\n```\n\n### AudioStreamCollection\n\n```python\naudios = yt.audio_streams\n\n# Properties\naudios.streams                    # All streams\naudios.best_stream                # Highest quality\naudios.worst_stream               # Lowest quality\naudios.available_languages        # [\"en-US\", \"pt-BR\", ...]\naudios.available_codecs           # [\"aac\", \"opus\", ...]\n\n# Filters\naudios.high_quality_streams       # ≥128kbps\naudios.lossless_quality_streams   # ≥320kbps \u0026 ≥48kHz\naudios.stereo_streams             # 2 channels\naudios.surround_streams           # \u003e2 channels\n\n# Methods\naudios.get_by_language(\"en-US\", fallback=True)\naudios.get_by_codec(\"aac\")\naudios.get_by_bitrate_range(min_bitrate=128)\naudios.get_by_sample_rate_range(min_rate=44100)\n```\n\n### SubtitleStream\n\n```python\nstream = yt.subtitle_streams.manual_subtitles[0]\n\n# Metadata\nstream.language                   # Language code\nstream.language_name              # Language name\nstream.extension                  # \"srt\", \"vtt\"\n\n# Flags\nstream.is_manual                  # Human-created\nstream.is_auto_generated          # Auto-generated\n\n# Download\nstream.url                        # Direct URL\n```\n\n### SubtitleStreamCollection\n\n```python\nsubs = yt.subtitle_streams\n\n# Properties\nsubs.streams                      # All streams\nsubs.available_languages          # Language codes\nsubs.available_language_names     # Language names\n\n# Filters\nsubs.manual_subtitles             # Human-created only\nsubs.auto_generated_subtitles     # Auto-generated only\n\n# Methods\nsubs.get_by_language(\"en\", fallback=True)\n```\n\n### YouTubeExtractor\n\n```python\nfrom streamsnapper import YouTubeExtractor\n\nextractor = YouTubeExtractor()\n\n# Extract IDs\nvideo_id = extractor.extract_video_id(url)\nplaylist_id = extractor.extract_playlist_id(url, include_private=False)\n\n# Identify platform\nplatform = extractor.identify_platform(url)  # \"youtube\" or \"youtube_music\"\n```\n\n## 🛡️ Error Handling\n\n```python\nfrom streamsnapper import YouTube, ScrapingError, InvalidDataError\n\ntry:\n    yt = YouTube()\n    yt.extract(\"https://www.youtube.com/watch?v=invalid\")\n    yt.analyze_information()\nexcept ScrapingError as e:\n    print(f\"Extraction failed: {e}\")\nexcept InvalidDataError as e:\n    print(f\"Invalid data: {e}\")\n```\n\n## 📝 License\n\nMIT License - see [LICENSE](LICENSE) file\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhenrique-coder%2Fstreamsnapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhenrique-coder%2Fstreamsnapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhenrique-coder%2Fstreamsnapper/lists"}