Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ jobs:
--hidden-import=six --hidden-import=pathvalidate \
--hidden-import=xml.etree.ElementTree \
--hidden-import=pywidevine \
--hidden-import=pyplayready \
--hidden-import=Cryptodome.Cipher --hidden-import=Cryptodome.Cipher.AES \
--hidden-import=Cryptodome.Util --hidden-import=Cryptodome.Util.Padding \
--hidden-import=Cryptodome.Random \
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,6 @@ working_proxies.json
start.sh
.DS_Store
GUI/db.sqlite3
console.log
console.log
/.github/script/domains.json
/.cache
2 changes: 1 addition & 1 deletion GUI/searchapp/api/altadefinizione.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __init__(self):

def _load_config(self):
"""Load site configuration."""
self.base_url = (config_manager.get_site("altadefinizione", "full_url") or "").rstrip("/")
self.base_url = (config_manager.domain.get("altadefinizione", "full_url") or "").rstrip("/")

def _get_search_fn(self):
"""Lazy load the search function."""
Expand Down
2 changes: 1 addition & 1 deletion GUI/searchapp/api/animeunity.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(self):

def _load_config(self):
"""Load site configuration."""
self.base_url = (config_manager.get_site("animeunity", "full_url") or "").rstrip("/")
self.base_url = config_manager.domain.get("animeunity", "full_url").rstrip("/")

def _get_search_fn(self):
"""Lazy load the search function."""
Expand Down
2 changes: 1 addition & 1 deletion GUI/searchapp/api/streamingcommunity.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __init__(self):

def _load_config(self):
"""Load site configuration."""
self.base_url = config_manager.get_site("streamingcommunity", "full_url").rstrip("/") + "/it"
self.base_url = config_manager.domain.get("streamingcommunity", "full_url").rstrip("/") + "/it"

def _get_search_fn(self):
"""Lazy load the search function."""
Expand Down
49 changes: 2 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div align="center">

<img src="https://i.postimg.cc/Y9t2XgB1/z562m3.png" alt="StreamingCommunity Logo" width="110" style="background: transparent;">
<img src="https://i.postimg.cc/Y9t2XgB1/z562m3.png" alt="StreamingCommunity Logo" width="110" style="background: transparent;"><br><br>

[![PyPI Version](https://img.shields.io/pypi/v/streamingcommunity?logo=pypi&logoColor=white&labelColor=2d3748&color=3182ce&style=for-the-badge)](https://pypi.org/project/streamingcommunity/)
[![Last Commit](https://img.shields.io/github/last-commit/Arrowar/StreamingCommunity?logo=git&logoColor=white&labelColor=2d3748&color=805ad5&style=for-the-badge)](https://github.com/Arrowar/StreamingCommunity/commits)
Expand Down Expand Up @@ -269,39 +269,6 @@ You can change some behaviors by tweaking the configuration file. The configurat
- 480p (640x480)
- 360p (640x360)


#### Output format Options
Final video will be saved with the selected extension. For each format, specific subtitles parameters need to be set in the `M3U8_CONVERSION` section.

> Note: if you want **ASS subtitles**, use `extension: "mkv"` and set `param_subtitles` to `["-c:s","ass"]`
> (or `["-c:s","copy"]` if the input subtitles are already ASS and you just want to mux them).

MP4 example:
```json
{
"M3U8_CONVERSION": {
"param_subtitles": [
"-c:s",
"mov_text"
],
"extension": "mp4"
}
}
```

MKV example (WebVTT):
```json
{
"M3U8_CONVERSION": {
"param_subtitles": [
"-c:s",
"webvtt"
],
"extension": "mkv"
}
}
```

#### Link options
- `get_only_link`: Return M3U8 playlist/index URL instead of downloading

Expand Down Expand Up @@ -555,14 +522,6 @@ make LOCAL_DIR=/path/to/download run-container

The `run-container` command mounts also the `config.json` file, so any change to the configuration file is reflected immediately without having to rebuild the image.


# Tutorials

- [Windows](https://www.youtube.com/watch?v=mZGqK4wdN-k)
- [Linux](https://www.youtube.com/watch?v=0qUNXPE_mTg)
- [Pypy](https://www.youtube.com/watch?v=C6m9ZKOK0p4)


# Useful Project

## 🎯 [Unit3Dup](https://github.com/31December99/Unit3Dup)
Expand All @@ -571,10 +530,6 @@ Bot in Python per la generazione e l'upload automatico di torrent su tracker bas
## 🇮🇹 [MammaMia](https://github.com/UrloMythus/MammaMia)
Addon per Stremio che consente lo streaming HTTPS di film, serie, anime e TV in diretta in lingua italiana.

## 🧩 [streamingcommunity-unofficialapi](https://github.com/Blu-Tiger/streamingcommunity-unofficialapi)
API non ufficiale per accedere ai contenuti del sito italiano StreamingCommunity.


# Disclaimer
> **Note:** This software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.

Expand All @@ -585,4 +540,4 @@ API non ufficiale per accedere ai contenuti del sito italiano StreamingCommunity
**Made with ❤️ for streaming lovers**

*If you find this project useful, consider starring it! ⭐*
</div>
</div>
30 changes: 23 additions & 7 deletions StreamingCommunity/Api/Player/vixcloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,21 +193,32 @@ def parse(cls, js_string):


class VideoSource:
def __init__(self, url: str, is_series: bool, media_id: int = None):
def __init__(self, url: str, is_series: bool, media_id: int = None, tmdb_data: Dict[str, Any] = None):
"""
Initialize video source for streaming site.

Args:
- url (str): The URL of the streaming site.
- is_series (bool): Flag for series or movie content
- media_id (int, optional): Unique identifier for media item
- tmdb_data (dict, optional): TMDB data with 'id', 's' (season), 'e' (episode)
"""
self.headers = {'user-agent': get_userAgent()}
self.url = url
self.is_series = is_series
self.media_id = media_id
self.iframe_src = None
self.window_parameter = None

# Store TMDB data if provided
if tmdb_data is not None:
self.tmdb_id = tmdb_data.get('id')
self.season_number = tmdb_data.get('s')
self.episode_number = tmdb_data.get('e')
else:
self.tmdb_id = None
self.season_number = None
self.episode_number = None

def get_iframe(self, episode_id: int) -> None:
"""
Expand Down Expand Up @@ -259,13 +270,18 @@ def parse_script(self, script_text: str) -> None:
def get_content(self) -> None:
"""
Fetch and process video content from iframe source.

Workflow:
- Validate iframe source
- Retrieve content
- Parse embedded script
"""
try:
# If TMDB ID is provided, use direct vixsrc.to URL
if self.tmdb_id is not None:
console.print("[red]Using API V.2")
if self.is_series:
if self.season_number is not None and self.episode_number is not None:
self.iframe_src = f"https://vixsrc.to/tv/{self.tmdb_id}/{self.season_number}/{self.episode_number}/?lang=it"
else:
self.iframe_src = f"https://vixsrc.to/movie/{self.tmdb_id}/?lang=it"

# Fetch content from iframe source
if self.iframe_src is not None:
response = create_client(headers=self.headers).get(self.iframe_src)
response.raise_for_status()
Expand Down Expand Up @@ -357,4 +373,4 @@ def get_embed(self, episode_id: int):

except Exception as e:
logging.error(f"Error fetching embed URL: {e}")
return None
return None
2 changes: 1 addition & 1 deletion StreamingCommunity/Api/Service/altadefinizione/film.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

# Variable
console = Console()
extension_output = config_manager.get("M3U8_CONVERSION", "extension")
extension_output = config_manager.config.get("M3U8_CONVERSION", "extension")


def download_film(select_title: MediaItem) -> str:
Expand Down
2 changes: 1 addition & 1 deletion StreamingCommunity/Api/Service/altadefinizione/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
# Variable
msg = Prompt()
console = Console()
extension_output = config_manager.get("M3U8_CONVERSION", "extension")
extension_output = config_manager.config.get("M3U8_CONVERSION", "extension")


def download_video(index_season_selected: int, index_episode_selected: int, scrape_serie: GetSerieInfo) -> Tuple[str,bool]:
Expand Down
1 change: 0 additions & 1 deletion StreamingCommunity/Api/Service/animeunity/film.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from StreamingCommunity.Api.Player.vixcloud import VideoSourceAnime



# Variable
console = Console()

Expand Down
1 change: 0 additions & 1 deletion StreamingCommunity/Api/Service/animeworld/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from StreamingCommunity.Util.table import TVShowManager



# Variable
console = Console()
media_search_manager = MediaManager()
Expand Down
35 changes: 11 additions & 24 deletions StreamingCommunity/Api/Service/crunchyroll/film.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@
from StreamingCommunity.Lib.DASH.downloader import DASH_Downloader


# Logi
# Logic
from .util.get_license import get_playback_session, CrunchyrollClient


# Variable
console = Console()
extension_output = config_manager.get("M3U8_CONVERSION", "extension")
extension_output = config_manager.config.get("M3U8_CONVERSION", "extension")


def download_film(select_title: MediaItem) -> str:
"""
Downloads a film using the provided film ID, title name, and domain.
Downloads a film.

Parameters:
- select_title (MediaItem): The selected media item.
Expand All @@ -38,28 +38,21 @@ def download_film(select_title: MediaItem) -> str:

# Initialize Crunchyroll client
client = CrunchyrollClient()
if not client.start():
console.print("[red]Failed to authenticate with Crunchyroll.")
return None, True

# Define filename and path for the downloaded video
# Define filename and path
mp4_name = f"{os_manager.get_sanitize_file(select_title.name, select_title.date)}.{extension_output}"
mp4_path = os.path.join(site_constants.MOVIE_FOLDER, mp4_name.replace(f".{extension_output}", ""))

# Get playback session
# Extract media ID
url_id = select_title.get('url').split('/')[-1]
playback_result = get_playback_session(client, url_id)

# Check if access was denied (403)
if playback_result is None:
console.print("[red]✗ Access denied: This content requires a premium subscription")
return None, False

mpd_url, mpd_headers, mpd_list_sub, token, _ = playback_result
# Get playback session
mpd_url, mpd_headers, mpd_list_sub, token, audio_locale = get_playback_session(client, url_id, None)

# Parse playback token from mpd_url
# Parse playback token from URL
parsed_url = urlparse(mpd_url)
query_params = parse_qs(parsed_url.query)
playback_guid = query_params.get('playbackGuid', [token])[0] if query_params.get('playbackGuid') else token

# Download the film
dash_process = DASH_Downloader(
Expand All @@ -74,7 +67,7 @@ def download_film(select_title: MediaItem) -> str:
license_headers = mpd_headers.copy()
license_headers.update({
"x-cr-content-id": url_id,
"x-cr-video-token": query_params['playbackGuid'][0],
"x-cr-video-token": playback_guid,
})

if dash_process.download_and_decrypt(custom_headers=license_headers):
Expand All @@ -88,11 +81,5 @@ def download_film(select_title: MediaItem) -> str:
os.remove(status['path'])
except Exception:
pass

# Delete stream after download to avoid TOO_MANY_ACTIVE_STREAMS
playback_token = token or query_params.get('playbackGuid', [None])[0]
if playback_token:
client.delete_active_stream(url_id, playback_token)
console.print("[dim]Playback session closed")


return status['path'], status['stopped']
Loading