main data
This commit is contained in:
55
README.md
Normal file
55
README.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Kivy Media Player
|
||||
|
||||
This project is a media player application built using Kivy. It allows users to play video files, display images, and manage settings for quick connect codes and server configurations. The application checks for updates to the playlist every five minutes while running in full screen.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
kivy-media-player
|
||||
├── src
|
||||
│ ├── main.py # Entry point of the Kivy application
|
||||
│ ├── settings.py # Manages the settings page
|
||||
│ ├── media_player.py # Handles media playback
|
||||
│ ├── utils.py # Utility functions for downloading files and updating playlists
|
||||
│ ├── kv
|
||||
│ │ ├── main.kv # Layout for the main application window
|
||||
│ │ ├── settings.kv # Layout for the settings page
|
||||
│ │ └── media_player.kv # Layout for the media player screen
|
||||
│ └── assets
|
||||
│ ├── images # Directory for image files
|
||||
│ └── videos # Directory for video files
|
||||
├── requirements.txt # Project dependencies
|
||||
└── README.md # Documentation for the project
|
||||
```
|
||||
|
||||
## Setup Instructions
|
||||
|
||||
1. Clone the repository:
|
||||
```
|
||||
git clone <repository-url>
|
||||
cd kivy-media-player
|
||||
```
|
||||
|
||||
2. Install the required dependencies:
|
||||
```
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
3. Run the application:
|
||||
```
|
||||
python src/main.py
|
||||
```
|
||||
|
||||
## Usage Guidelines
|
||||
|
||||
- Upon launching the application, users can navigate to the settings page to enter their quick connect code and server IP/domain.
|
||||
- The media player screen allows users to view images and play videos from the playlist.
|
||||
- The application automatically checks for updates to the playlist every five minutes.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please feel free to submit a pull request or open an issue for any suggestions or improvements.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License. See the LICENSE file for more details.
|
||||
4
requirements.txt
Normal file
4
requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
kivy
|
||||
requests
|
||||
watchdog
|
||||
Pillow
|
||||
BIN
src/__pycache__/media_player.cpython-311.pyc
Normal file
BIN
src/__pycache__/media_player.cpython-311.pyc
Normal file
Binary file not shown.
BIN
src/__pycache__/settings.cpython-311.pyc
Normal file
BIN
src/__pycache__/settings.cpython-311.pyc
Normal file
Binary file not shown.
1
src/assets/images
Normal file
1
src/assets/images
Normal file
@@ -0,0 +1 @@
|
||||
This file is intentionally left blank.
|
||||
1
src/assets/videos
Normal file
1
src/assets/videos
Normal file
@@ -0,0 +1 @@
|
||||
# This directory is intended to contain video files for the media player application.
|
||||
BIN
src/instance/dashboard.db
Normal file
BIN
src/instance/dashboard.db
Normal file
Binary file not shown.
45
src/kv/main.kv
Normal file
45
src/kv/main.kv
Normal file
@@ -0,0 +1,45 @@
|
||||
<contents of /kivy-media-player/kivy-media-player/src/kv/main.kv>
|
||||
|
||||
<ScreenManager>:
|
||||
MainScreen:
|
||||
SettingsScreen:
|
||||
|
||||
<MainScreen>:
|
||||
name: 'main'
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
Label:
|
||||
text: 'Welcome to the Media Player'
|
||||
font_size: 32
|
||||
size_hint_y: None
|
||||
height: 50
|
||||
Button:
|
||||
text: 'Go to Settings'
|
||||
on_press: root.manager.current = 'settings'
|
||||
Button:
|
||||
text: 'Play Media'
|
||||
on_press: app.play_media()
|
||||
|
||||
<SettingsScreen>:
|
||||
name: 'settings'
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
Label:
|
||||
text: 'Settings'
|
||||
font_size: 32
|
||||
size_hint_y: None
|
||||
height: 50
|
||||
TextInput:
|
||||
id: quick_connect_code
|
||||
hint_text: 'Enter Quick Connect Code'
|
||||
multiline: False
|
||||
TextInput:
|
||||
id: server_ip
|
||||
hint_text: 'Enter Server IP or Domain'
|
||||
multiline: False
|
||||
Button:
|
||||
text: 'Save Settings'
|
||||
on_press: app.save_settings(quick_connect_code.text, server_ip.text)
|
||||
Button:
|
||||
text: 'Back to Main'
|
||||
on_press: root.manager.current = 'main'
|
||||
52
src/kv/media_player.kv
Normal file
52
src/kv/media_player.kv
Normal file
@@ -0,0 +1,52 @@
|
||||
<contents of /kivy-media-player/kivy-media-player/src/kv/media_player.kv>
|
||||
|
||||
<MediaPlayerScreen>:
|
||||
name: 'media_player'
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
|
||||
Video:
|
||||
id: video_player
|
||||
state: 'stop'
|
||||
options: {'eos': 'stop'}
|
||||
|
||||
BoxLayout:
|
||||
size_hint_y: None
|
||||
height: '50dp'
|
||||
Button:
|
||||
text: 'Play'
|
||||
on_press: root.play_video()
|
||||
Button:
|
||||
text: 'Pause'
|
||||
on_press: root.pause_video()
|
||||
Button:
|
||||
text: 'Stop'
|
||||
on_press: root.stop_video()
|
||||
Button:
|
||||
text: 'Next'
|
||||
on_press: root.next_video()
|
||||
|
||||
Image:
|
||||
id: image_display
|
||||
allow_stretch: True
|
||||
keep_ratio: True
|
||||
size_hint_y: None
|
||||
height: '300dp'
|
||||
|
||||
Label:
|
||||
id: playlist_label
|
||||
text: 'Playlist'
|
||||
size_hint_y: None
|
||||
height: '30dp'
|
||||
|
||||
ScrollView:
|
||||
size_hint_y: None
|
||||
height: '200dp'
|
||||
GridLayout:
|
||||
id: playlist
|
||||
cols: 1
|
||||
size_hint_y: None
|
||||
height: self.minimum_height
|
||||
|
||||
<MediaPlayerScreen>:
|
||||
on_enter: root.load_playlist()
|
||||
32
src/kv/settings.kv
Normal file
32
src/kv/settings.kv
Normal file
@@ -0,0 +1,32 @@
|
||||
<settings.kv>
|
||||
<SettingsScreen>:
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
padding: 10
|
||||
spacing: 10
|
||||
|
||||
Label:
|
||||
text: 'Settings'
|
||||
font_size: 24
|
||||
size_hint_y: None
|
||||
height: 40
|
||||
|
||||
Label:
|
||||
text: 'Quick Connect Code:'
|
||||
TextInput:
|
||||
id: quick_connect_code
|
||||
multiline: False
|
||||
|
||||
Label:
|
||||
text: 'Server IP/Domain Name:'
|
||||
TextInput:
|
||||
id: server_ip
|
||||
multiline: False
|
||||
|
||||
Button:
|
||||
text: 'Save Settings'
|
||||
on_press: app.save_settings(quick_connect_code.text, server_ip.text)
|
||||
|
||||
Button:
|
||||
text: 'Back to Main'
|
||||
on_press: app.change_screen('main')
|
||||
21
src/main.py
Normal file
21
src/main.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from kivy.app import App
|
||||
from kivy.uix.screenmanager import ScreenManager, Screen
|
||||
from kivy.clock import Clock
|
||||
from settings import Settings
|
||||
from media_player import MediaPlayer
|
||||
|
||||
class MainApp(App):
|
||||
def build(self):
|
||||
self.title = "Kivy Media Player"
|
||||
self.sm = ScreenManager()
|
||||
self.sm.add_widget(Settings(name='settings'))
|
||||
self.sm.add_widget(MediaPlayer(name='media_player'))
|
||||
Clock.schedule_interval(self.check_playlist_updates, 300) # Check for updates every 5 minutes
|
||||
return self.sm
|
||||
|
||||
def check_playlist_updates(self, dt):
|
||||
# Logic to check for updates in the playlist
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
MainApp().run()
|
||||
64
src/media_player.py
Normal file
64
src/media_player.py
Normal file
@@ -0,0 +1,64 @@
|
||||
from kivy.app import App
|
||||
from kivy.uix.screenmanager import ScreenManager, Screen
|
||||
from kivy.clock import Clock
|
||||
from kivy.core.window import Window
|
||||
from kivy.uix.video import Video
|
||||
from kivy.uix.image import Image
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
import requests
|
||||
import os
|
||||
import json
|
||||
|
||||
class MediaPlayer(Screen):
|
||||
def __init__(self, **kwargs):
|
||||
super(MediaPlayer, self).__init__(**kwargs)
|
||||
self.playlist = []
|
||||
self.current_index = 0
|
||||
self.video_player = Video()
|
||||
self.image_display = Image()
|
||||
self.layout = BoxLayout(orientation='vertical')
|
||||
self.layout.add_widget(self.video_player)
|
||||
self.layout.add_widget(self.image_display)
|
||||
self.add_widget(self.layout)
|
||||
Clock.schedule_interval(self.check_playlist_updates, 300) # Check for updates every 5 minutes
|
||||
|
||||
def on_enter(self):
|
||||
self.load_playlist()
|
||||
self.play_media()
|
||||
|
||||
def load_playlist(self):
|
||||
# Load playlist from the server or local storage
|
||||
try:
|
||||
response = requests.get('http://yourserver.com/api/playlist')
|
||||
response.raise_for_status() # Raise an exception for HTTP errors
|
||||
self.playlist = response.json()
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Failed to load playlist: {e}")
|
||||
except json.JSONDecodeError:
|
||||
print("Failed to parse playlist JSON")
|
||||
|
||||
def play_media(self):
|
||||
if self.playlist:
|
||||
media = self.playlist[self.current_index]
|
||||
if media['type'] == 'video':
|
||||
self.video_player.source = media['url']
|
||||
self.video_player.play()
|
||||
self.image_display.source = ''
|
||||
elif media['type'] == 'image':
|
||||
self.image_display.source = media['url']
|
||||
self.video_player.source = ''
|
||||
self.image_display.reload()
|
||||
|
||||
def check_playlist_updates(self, dt):
|
||||
self.load_playlist()
|
||||
self.play_media()
|
||||
|
||||
class MediaPlayerApp(App):
|
||||
def build(self):
|
||||
Window.fullscreen = True
|
||||
sm = ScreenManager()
|
||||
sm.add_widget(MediaPlayer(name='media_player'))
|
||||
return sm
|
||||
|
||||
if __name__ == '__main__':
|
||||
MediaPlayerApp().run()
|
||||
1
src/settings.json
Normal file
1
src/settings.json
Normal file
@@ -0,0 +1 @@
|
||||
{"settings": {"quick_connect_code": "", "server_ip": ""}}
|
||||
51
src/settings.py
Normal file
51
src/settings.py
Normal file
@@ -0,0 +1,51 @@
|
||||
from kivy.app import App
|
||||
from kivy.uix.screenmanager import Screen
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.label import Label
|
||||
from kivy.uix.textinput import TextInput
|
||||
from kivy.uix.button import Button
|
||||
from kivy.properties import StringProperty
|
||||
from kivy.storage.jsonstore import JsonStore
|
||||
|
||||
class Settings(Screen):
|
||||
quick_connect_code = StringProperty("")
|
||||
server_ip = StringProperty("")
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(Settings, self).__init__(**kwargs)
|
||||
self.store = JsonStore('settings.json')
|
||||
self.load_settings()
|
||||
|
||||
self.layout = BoxLayout(orientation='vertical')
|
||||
|
||||
self.server_ip_input = TextInput(hint_text='Server IP or Domain')
|
||||
self.quick_connect_code_input = TextInput(hint_text='Quick Connect Code')
|
||||
|
||||
self.layout.add_widget(Label(text='Server IP or Domain:'))
|
||||
self.layout.add_widget(self.server_ip_input)
|
||||
self.layout.add_widget(Label(text='Quick Connect Code:'))
|
||||
self.layout.add_widget(self.quick_connect_code_input)
|
||||
|
||||
self.save_button = Button(text='Save', on_press=self.save_settings)
|
||||
self.layout.add_widget(self.save_button)
|
||||
|
||||
self.add_widget(self.layout)
|
||||
|
||||
def load_settings(self):
|
||||
if self.store.exists('settings'):
|
||||
settings = self.store.get('settings')
|
||||
self.quick_connect_code = settings.get('quick_connect_code', "")
|
||||
self.server_ip = settings.get('server_ip', "")
|
||||
|
||||
def save_settings(self, instance=None):
|
||||
self.store.put('settings', quick_connect_code=self.quick_connect_code, server_ip=self.server_ip)
|
||||
server_ip = self.server_ip_input.text
|
||||
quick_connect_code = self.quick_connect_code_input.text
|
||||
# Save the settings (e.g., to a file or database)
|
||||
print(f'Settings saved: Server IP = {server_ip}, Quick Connect Code = {quick_connect_code}')
|
||||
|
||||
def on_quick_connect_code(self, instance, value):
|
||||
self.save_settings()
|
||||
|
||||
def on_server_ip(self, instance, value):
|
||||
self.save_settings()
|
||||
29
src/utils.py
Normal file
29
src/utils.py
Normal file
@@ -0,0 +1,29 @@
|
||||
def download_file(url, destination):
|
||||
import requests
|
||||
response = requests.get(url)
|
||||
if response.status_code == 200:
|
||||
with open(destination, 'wb') as f:
|
||||
f.write(response.content)
|
||||
return True
|
||||
return False
|
||||
|
||||
def check_for_playlist_updates(playlist_url, current_playlist):
|
||||
import requests
|
||||
response = requests.get(playlist_url)
|
||||
if response.status_code == 200:
|
||||
new_playlist = response.json()
|
||||
if new_playlist != current_playlist:
|
||||
return new_playlist
|
||||
return None
|
||||
|
||||
def schedule_playlist_update(playlist_url, current_playlist, update_interval=300):
|
||||
from threading import Timer
|
||||
|
||||
def check_updates():
|
||||
new_playlist = check_for_playlist_updates(playlist_url, current_playlist)
|
||||
if new_playlist:
|
||||
current_playlist.clear()
|
||||
current_playlist.extend(new_playlist)
|
||||
Timer(update_interval, check_updates).start()
|
||||
|
||||
check_updates()
|
||||
Reference in New Issue
Block a user