Streams the first available stream for the given channel. It uses the channel’s assigned StreamProfile. A persistent Redis lock is used to prevent concurrent streaming on the same channel.
(request, channel_uuid)
| 31 | |
| 32 | |
| 33 | def stream_view(request, channel_uuid): |
| 34 | """ |
| 35 | Streams the first available stream for the given channel. |
| 36 | It uses the channel’s assigned StreamProfile. |
| 37 | A persistent Redis lock is used to prevent concurrent streaming on the same channel. |
| 38 | """ |
| 39 | try: |
| 40 | redis_host = getattr(settings, "REDIS_HOST", "localhost") |
| 41 | redis_port = int(getattr(settings, "REDIS_PORT", 6379)) |
| 42 | redis_db = int(getattr(settings, "REDIS_DB", "0")) |
| 43 | redis_password = getattr(settings, "REDIS_PASSWORD", "") |
| 44 | redis_user = getattr(settings, "REDIS_USER", "") |
| 45 | ssl_params = getattr(settings, "REDIS_SSL_PARAMS", {}) |
| 46 | redis_client = redis.Redis( |
| 47 | host=redis_host, |
| 48 | port=redis_port, |
| 49 | db=redis_db, |
| 50 | password=redis_password if redis_password else None, |
| 51 | username=redis_user if redis_user else None, |
| 52 | **ssl_params |
| 53 | ) |
| 54 | |
| 55 | # Retrieve the channel by the provided stream_id. |
| 56 | channel = Channel.objects.get(uuid=channel_uuid) |
| 57 | logger.debug("Channel retrieved: ID=%s, Name=%s", channel.id, channel.name) |
| 58 | |
| 59 | # Ensure the channel has at least one stream. |
| 60 | if not channel.streams.exists(): |
| 61 | logger.error("No streams found for channel ID=%s", channel.id) |
| 62 | return HttpResponseServerError("No stream found for this channel.") |
| 63 | |
| 64 | active_stream = None |
| 65 | m3u_account = None |
| 66 | active_profile = None |
| 67 | lock_key = None |
| 68 | persistent_lock = None |
| 69 | |
| 70 | streams = channel.streams.all().order_by('channelstream__order') |
| 71 | logger.debug(f'Found {len(streams)} streams for channel {channel.channel_number}') |
| 72 | for stream in streams: |
| 73 | # Get the first available stream. |
| 74 | logger.debug("Checking stream: ID=%s, Name=%s", stream.id, stream.name) |
| 75 | |
| 76 | # Retrieve the M3U account associated with the stream. |
| 77 | m3u_account = stream.m3u_account |
| 78 | logger.debug("Stream M3U account ID=%s, Name=%s", m3u_account.id, m3u_account.name) |
| 79 | |
| 80 | # Use the custom URL if available; otherwise, use the standard URL. |
| 81 | input_url = stream.url |
| 82 | logger.debug("Input URL: %s", input_url) |
| 83 | |
| 84 | # Determine which profile we can use. |
| 85 | m3u_profiles = m3u_account.profiles.all() |
| 86 | default_profile = next((obj for obj in m3u_profiles if obj.is_default), None) |
| 87 | profiles = [obj for obj in m3u_profiles if not obj.is_default] |
| 88 | |
| 89 | # -- Loop through profiles and pick the first active one -- |
| 90 | for profile in [default_profile] + profiles: |
nothing calls this directly
no test coverage detected