Skip to content
Open
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
156 changes: 156 additions & 0 deletions Random Number Generator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
## Install Dependencies:

- yt_dlp
- cv2 (OpenCV)
- numpy

Install the required packages:

python -m pip install yt-dlp opencv-python numpy

## How to run:

Run the script in your IDE or from a terminal:

python random_number_generator.py

## How it works:

The script generates random numbers by extracting color-channel values
from random pixels extracted in frames captured from randomly selected
predefined YouTube livestreams.

Process:

```text
Youtube URL
-> yt_dlp -> extracts the stream URL
-> cv2 (OpenCV) -> opens the stream and captures a frame
-> numpy -> selects random positions in the frame
-> extracts a random color-channel value
```

### Frame Extraction:

After a frame is captured, its dimensions are extracted:

```python
h = 1080
w = 1920
px = 3
```

Where:

- 'h' = frame height (1080 pixels)
- 'w' = frame width (1920 pixels)
- 'px' = number of channels per pixel

Most YouTube video frames are standard color images, so:

```text
px = 3
```

represents:

```text
Channel 0 -> Blue
Channel 1 -> Green
Channel 2 -> Red
```

The script then randomly selecs:
- A row position
- A column position
- A color channel

Example random selections:

```python
row = 527
column = 1300
channel = 2
```

This returns a frame:

```python
frame[527,1300]
```
which may return:

```python
[45, 182, 230]
```

OpenCV stores colors in BGR order:

```text
Blue = 45
Green = 182
Red = 230
```

Since the randomly selected channel is "2" from:

```python
row = 527
column = 1300
channel = 2
```

The script returns:

```python
230
```

Which is the 3rd element of the channel frame:

```python
[45, 182, 230]
```

## Notes

Because a single color channel is extracted, the generated values currently range between 0-255.
The visual characteristics of the livestream can influence the distribution of values.

Example:

- Snow-heavy videos (such as the Polar Bear Tundra livestream) often contain many bright pixels and may
produce different distributions compared to colorful scenes (such as the Tropical Reef Aquarium).

- Highly colorful streams may produce a wider variety of values.

Future versions may expand the range beyond a single color-channel value.

## Current Available Livestreams

# Jellyfish Tank
"https://www.youtube.com/watch?v=1rvCfsW_qTA",

# Tropical Reef Aquarium
"https://www.youtube.com/watch?v=DHUnz4dyb54",

# Polar Bear Tundra
"https://www.youtube.com/watch?v=kvJnsuyE0cs",

# Great Green Macaw Nest
"https://www.youtube.com/watch?v=OUc-R6Mtg0E",

# Bison Grasslands National Park
"https://www.youtube.com/watch?v=g6wxYiESkE4",

# Puffin Skomer Island
"https://www.youtube.com/watch?v=1pFTuCQGVZ0",

# Panda Chengdu Base
"https://www.youtube.com/watch?v=SUXPnIEpbn4",

# Grace the Gorilla
"https://www.youtube.com/watch?v=672cUSe69J0",

# Bald Eagle Big Bear
"https://www.youtube.com/watch?v=B4-L2nfGcuE"
221 changes: 221 additions & 0 deletions Random Number Generator/random_number_generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
import yt_dlp
import cv2
import numpy as np


# -----------------YouTube livestream URLs------------------ #
URLs = [
# Jellyfish Tank
"https://www.youtube.com/watch?v=1rvCfsW_qTA",

# Tropical Reef Aquarium
"https://www.youtube.com/watch?v=DHUnz4dyb54",

# Polar Bear Tundra
"https://www.youtube.com/watch?v=kvJnsuyE0cs",

# Great Green Macaw Nest
"https://www.youtube.com/watch?v=OUc-R6Mtg0E",

# Bison Grasslands National Park
"https://www.youtube.com/watch?v=g6wxYiESkE4",

# Puffin Skomer Island
"https://www.youtube.com/watch?v=1pFTuCQGVZ0",

# Panda Chengdu Base
"https://www.youtube.com/watch?v=SUXPnIEpbn4",

# Grace the Gorilla
"https://www.youtube.com/watch?v=672cUSe69J0",

# Bald Eagle Big Bear
"https://www.youtube.com/watch?v=B4-L2nfGcuE"
]

# yt-dlp set options
options = {
"quiet": True,
"no_warnings": True,
"logger": None
}

def get_single_frame():
"""
Capture a single frame from a random available YouTube livestream.

The function randomly iterates through a predefined list of livestream URLs,
attempts to extract the direct stream URL using yt-dlp, and captures
one video frame using OpenCV.

Returns:
numpy.ndarray:
A single video frame if capture succeeds.

None:
Returned if all livestreams are offline or frame capture fails.
"""

random_urls = np.random.permutation(URLs)

for url in random_urls:
try:

# Extracts livestream URL and metadata without downloading
with yt_dlp.YoutubeDL(options) as ydl:
info = ydl.extract_info(url, download=False)
stream_url = info["url"]

capture_video = cv2.VideoCapture(stream_url)
ret, frame = capture_video.read()
capture_video.release()

if ret:
print(f"Frame captured Successfully: {url}")
return frame

print(f"Frame capture failed: {url}")

except Exception as e:
print(f"{url} livestream currently offline")

print("All livestreams are offline")
return None


def get_rand_px():
"""
Extract a random BGR channel value from a random pixel
within a captured livestream frame.

A single frame is captured from the first available livestream.
The function randomly selects:
- a row position
- a column position
- a color channel (B, G, or R)

Returns:
int:
Random pixel channel value between 0 and 255.

None:
Returned if frame capture fails.
"""

frame = get_single_frame()

if frame is None:
return None

# Get a random pixel's BGR value
h, w, px = frame.shape

pixel_value = int(frame[np.random.randint(0, h), np.random.randint(0, w),
np.random.randint(0, px)])
print(pixel_value)
return pixel_value


def sum_all(nums):
"""
Calculate the sum of all generated random numbers.

Returns:
int:
Sum of all values stored in random_numbers or
the single stored value if only one number exists.
"""

return sum(nums)


def avg(nums):
"""
Calculate the average of all generated random numbers.

Returns:
int:
Rounded average of all values stored in random_numbers or
the single stored value if only one number exists.
"""

return round(sum(nums)/len(nums))


def concat(nums):
"""
Concatenate all generated random numbers into a single integer.

Example:
[12, 45, 78] -> 124578

Returns:
int:
Concatenated integer of all random numbers or
the single stored value if only one number exists.
"""

return int("".join(map(str, nums)))


# -------------------------PROGRAM---------------------------- #
def main():

random_numbers = []

size = input("How many random numbers?\n> ")

while not size.isdigit() or not (1 <= int(size) <= 10):
print("Error: Please enter an integer between 1 and 10.")

size = input("How many random numbers? ")

size = int(size)

for i in range(size):
random_numbers.append(get_rand_px())

while True:

print("\n>>> COMMANDS <<<")

print("\n1 : Sum")
print("2 : Average")
print("3 : Concatenate")
print("4 : Print")
print("5 : Exit")

COM = input("> ")

while not COM.isdigit() or not (1 <= int(COM) <= 5):
print("Error: Please select a number between 1 and 5.")

print("\n1 : Sum")
print("2 : Average")
print("3 : Concatenate")
print("4 : Print all")
print("5 : Exit")

COM = input("> ")

COM = int(COM)

if COM == 1:
print(sum_all(random_numbers))

elif COM == 2:
print(avg(random_numbers))

elif COM == 3:
print(concat(random_numbers))

elif COM == 4:
print(*random_numbers)

elif COM == 5:
print("Good Bye")
break


if __name__ == "__main__":
main()