Aktualisiere Basis-URL auf 'https://www.serman.club' in local_podcast_generator.py und main.py; füge Funktion zum Extrahieren und Speichern von Episode-Covern hinzu.
This commit is contained in:
@ -16,7 +16,7 @@ from pathlib import Path
|
||||
|
||||
|
||||
class LocalPodcastGenerator:
|
||||
def __init__(self, audio_dir="../httpdocs/_audio", output_file="podcast_feed.xml", base_url="http://localhost:8087"):
|
||||
def __init__(self, audio_dir="../httpdocs/_audio", output_file="podcast_feed.xml", base_url="https://www.serman.club"):
|
||||
self.audio_dir = audio_dir
|
||||
self.output_file = output_file
|
||||
self.base_url = base_url.rstrip('/')
|
||||
@ -46,11 +46,21 @@ class LocalPodcastGenerator:
|
||||
artist = None
|
||||
album = None
|
||||
duration = None
|
||||
cover_data = None
|
||||
|
||||
if audio.tags:
|
||||
title = str(audio.tags.get('TIT2', [''])[0]) if audio.tags.get('TIT2') else None
|
||||
artist = str(audio.tags.get('TPE1', [''])[0]) if audio.tags.get('TPE1') else None
|
||||
album = str(audio.tags.get('TALB', [''])[0]) if audio.tags.get('TALB') else None
|
||||
|
||||
# Cover-Art extrahieren (APIC = Attached Picture)
|
||||
if 'APIC:' in audio.tags:
|
||||
cover_data = audio.tags.get('APIC:').data
|
||||
elif audio.tags.get('APIC'):
|
||||
# Fallback für andere APIC-Varianten
|
||||
apic_tags = [tag for tag in audio.tags if tag.startswith('APIC')]
|
||||
if apic_tags:
|
||||
cover_data = audio.tags.get(apic_tags[0]).data
|
||||
|
||||
# Dauer in Sekunden
|
||||
if hasattr(audio, 'info') and audio.info.length:
|
||||
@ -73,7 +83,8 @@ class LocalPodcastGenerator:
|
||||
'duration': duration,
|
||||
'file_size': file_size,
|
||||
'pub_date': pub_date,
|
||||
'filename': file_path.name
|
||||
'filename': file_path.name,
|
||||
'cover_data': cover_data
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
@ -86,9 +97,38 @@ class LocalPodcastGenerator:
|
||||
'duration': None,
|
||||
'file_size': file_path.stat().st_size,
|
||||
'pub_date': datetime.fromtimestamp(file_path.stat().st_mtime),
|
||||
'filename': file_path.name
|
||||
'filename': file_path.name,
|
||||
'cover_data': None
|
||||
}
|
||||
|
||||
def extract_episode_cover(self, metadata, episode_index):
|
||||
"""Extrahiert und speichert das Episode-Cover."""
|
||||
if not metadata['cover_data']:
|
||||
return None
|
||||
|
||||
try:
|
||||
# Erstelle Cover-Dateiname basierend auf MP3-Dateiname
|
||||
cover_filename = f"cover_{Path(metadata['filename']).stem}.jpg"
|
||||
|
||||
# Speichere Cover im httpdocs-Verzeichnis
|
||||
if "../httpdocs" in self.audio_dir:
|
||||
cover_path = Path("../httpdocs") / cover_filename
|
||||
else:
|
||||
cover_path = Path(cover_filename)
|
||||
|
||||
# Schreibe Cover-Daten in Datei
|
||||
with open(cover_path, 'wb') as f:
|
||||
f.write(metadata['cover_data'])
|
||||
|
||||
# Rückgabe der URL zum Cover
|
||||
cover_url = f"{self.base_url}/{cover_filename}"
|
||||
print(f" 🖼️ Cover extrahiert: {cover_filename}")
|
||||
return cover_url
|
||||
|
||||
except Exception as e:
|
||||
print(f" ⚠️ Fehler beim Extrahieren des Covers: {e}")
|
||||
return None
|
||||
|
||||
def format_duration(self, seconds):
|
||||
"""Formatiert die Dauer in HH:MM:SS Format."""
|
||||
if not seconds:
|
||||
@ -153,7 +193,7 @@ Ich spezialisiere mich auf House Music, die mehr als nur Beats bietet – sie er
|
||||
itunes_explicit.text = "false"
|
||||
|
||||
# Standard-Bild (kann später angepasst werden)
|
||||
image_url = f"{self.base_url}/podcast-cover.jpg"
|
||||
image_url = f"{self.base_url}/_img/podcast-cover.png"
|
||||
image = ET.SubElement(channel, "image")
|
||||
image_url_elem = ET.SubElement(image, "url")
|
||||
image_url_elem.text = image_url
|
||||
@ -168,9 +208,12 @@ Ich spezialisiere mich auf House Music, die mehr als nur Beats bietet – sie er
|
||||
print(f"📦 Erstelle RSS-Feed mit {len(mp3_files)} Episoden...")
|
||||
|
||||
# Items (Episoden) hinzufügen
|
||||
for mp3_file in mp3_files:
|
||||
for episode_index, mp3_file in enumerate(mp3_files):
|
||||
metadata = self.get_mp3_metadata(mp3_file)
|
||||
|
||||
# Episode-Cover extrahieren
|
||||
episode_cover_url = self.extract_episode_cover(metadata, episode_index)
|
||||
|
||||
item = ET.SubElement(channel, "item")
|
||||
|
||||
# Titel
|
||||
@ -220,6 +263,11 @@ Ich spezialisiere mich auf House Music, die mehr als nur Beats bietet – sie er
|
||||
itunes_explicit_item = ET.SubElement(item, "itunes:explicit")
|
||||
itunes_explicit_item.text = "false"
|
||||
|
||||
# Episode-Cover hinzufügen (falls vorhanden)
|
||||
if episode_cover_url:
|
||||
itunes_image_item = ET.SubElement(item, "itunes:image")
|
||||
itunes_image_item.set("href", episode_cover_url)
|
||||
|
||||
# Keywords/Tags basierend auf Dateiname
|
||||
if any(keyword in metadata['title'].lower() for keyword in ['organic', 'house']):
|
||||
itunes_keywords = ET.SubElement(item, "itunes:keywords")
|
||||
@ -309,8 +357,8 @@ def main():
|
||||
help="Verzeichnis mit MP3-Dateien (Standard: ../httpdocs/_audio)")
|
||||
parser.add_argument("-o", "--output", default="podcast_feed.xml",
|
||||
help="Ausgabedatei für den RSS-Feed (Standard: podcast_feed.xml)")
|
||||
parser.add_argument("-u", "--base-url", default="http://localhost:8087",
|
||||
help="Basis-URL für Audio-Dateien (Standard: http://localhost:8087)")
|
||||
parser.add_argument("-u", "--base-url", default="https://www.serman.club",
|
||||
help="Basis-URL für Audio-Dateien (Standard: https://www.serman.club)")
|
||||
parser.add_argument("-t", "--title", default="SERMAN - Organic House Podcast",
|
||||
help="Titel des Podcasts")
|
||||
parser.add_argument("--author", default="SERMAN",
|
||||
|
4
main.py
4
main.py
@ -16,8 +16,8 @@ def main():
|
||||
help="Verzeichnis mit MP3-Dateien (Standard: ../httpdocs/_audio)")
|
||||
parser.add_argument("-o", "--output", default="serman_podcast.xml",
|
||||
help="Ausgabedatei für den RSS-Feed (Standard: serman_podcast.xml)")
|
||||
parser.add_argument("-u", "--base-url", default="http://localhost:8087",
|
||||
help="Basis-URL für Audio-Dateien (Standard: http://localhost:8087)")
|
||||
parser.add_argument("-u", "--base-url", default="https://www.serman.club",
|
||||
help="Basis-URL für Audio-Dateien (Standard: https://www.serman.club)")
|
||||
parser.add_argument("--serve", action="store_true",
|
||||
help="Startet automatisch einen HTTP-Server nach der Generierung")
|
||||
parser.add_argument("--port", type=int, default=8087,
|
||||
|
Reference in New Issue
Block a user