je 1 Song von mehreren Playlists

Heyho!

Ich suche nach einer Möglichkeit, dass ich immer jeweils einen Song von einer Playlist spiele.

Also zb:

Playlist 1 = shuffled Song
Playlist 2 = shuffled song
Playlist 1 = shuffled Song

etc.

Würde nämlich gern ein Internetradio machen, wo immer 1 Song gespielt wird, dann ein Kabarrettausschnitt, dann wieder ein Song.

Hat jemand dazu eine Idee?

lg
 
Welches Betriebssystem? Welche Player-Software wird für's Internet-Radio verwendet?
 
heyho.

Also das ganze sollte auf Windows rennen wenn möglich.

Das Radio gibts noch nicht, daher nehm ich jede Software, der man diese Funktion beibringen kann.

lg
 
warum nicht aus 2 pools mit titeln eine neue playlist generieren in dem man abwechselnd aus jedem pool zufällig zieht?
 
Das sollte sich mit jeder beliebigen Script-Sprache realisieren lassen. Beide Playlisten einlesen und jeweils eine zufällige Zeile aus den Dateien nehmen. Diese dann zu einer neuen Playliste zusammenführen. Schliesslich sind M3U-Dateien auch nur Listen, in denen jede Zeile einem Eintrag/Titel entspricht.
 
Mir war gerade ein wenig langweilig.
Wenn du Lust hast Python zu nutzen.
Getestet mit Python 2.7. Sollte auch mit 3.* laufen, aber ehrlich gesagt, keine Ahnung ;)
Aufzurufen wie folgt:
Code:
python scriptname.py ZEILEN file1.m3u file2.m3u [fileX.m3u...] > DeineNeuePlaylist.m3u
ZEILEN ist natürlich mit der gewünschten Anzahl an Zeilen zu ersetzen.
Das Script dürfte Probleme mit unicode namen haben, aber windows auch (?)

Code:
if __name__ == '__main__':
    import sys
    import os
    import random
    import exceptions
    if len(sys.argv) < 4 or sys.argv[1] in ("-h", "--h", "-help", "--help"):
        print ("""
USAGE %s: lines file1 file2 [file3...]
ATTENTION: If one of the files is empty or every line is a comment, 
this script will hang in a nasty endless loop       
        """ % sys.argv[0])
        exit(0)
    try:
        lines = int(sys.argv[1])
    except exceptions.ValueError:
        print("The first argument need to be an int")
        exit(1)
    try:
        fds = [(open(fname, "rb"), os.path.getsize(fname)) for fname in sys.argv[2:]]
    except Exception as e:
        print("Failed to open a file (%s)" % str(e)) # yep i am lazy
        exit(2)
    while lines > 0:
        for fd, size in fds:
            while True: # as mentioned ... lazy
                fd.seek(random.randint(0, size-1))
                fd.readline() # skip one
                data = fd.readline()
                if len(data) == 0: # if we jumped into the last line
                    fd.seek(0)
                    data = fd.readline()
                data = data.strip()
                if data[0] != "#": break
            print(data)                 
        lines -= 1
 
Wow!

Deiner Langeweile sei Dank! :)

Werds gleich ausprobieren und euch Bescheid geben.

Thx, Thx, Thx!

Wenn das Radio dann mal steht kommst du in die Credits :)
 
Auch Python 2.7, lässt sich prinzipiell wie das Script oben nutzen und sollte etwas robuster/fehlertorleranter sein:
Code:
CDW@highlander-jr:~/projects/python/m3u_shuffle % python shuffler.py --lines=2 f1.m3u f2.m3u 
Sample3.mp3
testline1
Sample.mp3
testline2
CDW@highlander-jr:~/projects/python/m3u_shuffle % python shuffler.py f1.m3u f2.m3u
...
CDW@highlander-jr:~/projects/python/m3u_shuffle % python shuffler.py
usage: shuffler.py [-h] [--lines LINES] file [file ...]
shuffler.py: error: too few arguments
CDW@highlander-jr:~/projects/python/m3u_shuffle % python shuffler.py -h
usage: shuffler.py [-h] [--lines LINES] file [file ...]

Creates a new,random playlist.

positional arguments:
  file           file1 file2 ...

optional arguments:
  -h, --help     show this help message and exit
  --lines LINES
CDW@highlander-jr:~/projects/python/m3u_shuffle %
Also ab 1 Liste aufwärts.

Unterschiede:
1. es wird nicht immer zufällig ein Lied aus einer Playlist ausgewählt, sondern die Playlist wird gemischt und dann aus diesem "Pool" jeweil 1 Lied "entnommen", bis keine Lieder mehr da sind.
Werden weitere Lieder benötigt, wird wieder ein "Pool" gebildet und es geht vom Neuen los.
Das sollte vermeiden, dass gleiche Stücke mehrmals (bzw. in kurzen Abständen) hintereinander kommen (kann nur dann auftreten, wenn alle Lieder aus der Playlist entnommen wurden und diese neu gemischt wird - dann könnte es vorkommen, dass zuletzt entnommene Songs am Anfang der neu gebildeten Liste landen. Lässt sich aber auch darüber reden, ob und wie man das am besten vermeiden könnte ;) )

2. die Zeilenanzahlangabe über das Argument "--lines=X" ist optional (ansonsten wird die längste Playlist abgearbeitet) und kann beliebig groß sein.

Code:
[color=#008800][i]#! /usr/bin/env python[/i][/color]
[color=#008800][i]# -*- coding: utf-8 -*-[/i][/color]
[color=#AA22FF][b]from[/b][/color] [color=#0000FF][b]argparse[/b][/color] [color=#AA22FF][b]import[/b][/color] ArgumentParser
[color=#AA22FF][b]from[/b][/color] [color=#0000FF][b]random[/b][/color] [color=#AA22FF][b]import[/b][/color] shuffle

[color=#AA22FF][b]def[/b][/color] [color=#00A000]read_m3u[/color](name):
    [color=#AA22FF][b]with[/b][/color] [color=#AA22FF]open[/color](name,[color=#BB4444]'rb'[/color]) [color=#AA22FF][b]as[/b][/color] m3u_file:
        stripped [color=#666666]=[/color] (line[color=#666666].[/color]strip() [color=#AA22FF][b]for[/b][/color] line [color=#AA22FF][b]in[/b][/color] m3u_file)
        [color=#AA22FF][b]return[/b][/color] [line [color=#AA22FF][b]for[/b][/color] line [color=#AA22FF][b]in[/b][/color] stripped
                [color=#AA22FF][b]if[/b][/color] line [color=#AA22FF][b]and[/b][/color] [color=#AA22FF][b]not[/b][/color] line[color=#666666].[/color]startswith([color=#BB4444]'#'[/color])]

[color=#AA22FF][b]def[/b][/color] [color=#00A000]random_line_gen[/color](playlist):
    [color=#AA22FF][b]while[/b][/color] [color=#AA22FF]True[/color]:
        shuffle(playlist)
        [color=#AA22FF][b]for[/b][/color] line [color=#AA22FF][b]in[/b][/color] playlist:
            [color=#AA22FF][b]yield[/b][/color] line

[color=#AA22FF][b]def[/b][/color] [color=#00A000]gen_list[/color](playlists, lines[color=#666666]=[/color][color=#AA22FF]None[/color]):
    [color=#AA22FF][b]if[/b][/color] [color=#AA22FF][b]not[/b][/color] lines:
        lines [color=#666666]=[/color] [color=#AA22FF]len[/color]([color=#AA22FF]max[/color](playlists, key[color=#666666]=[/color][color=#AA22FF]len[/color]))
    shuffled_playlist [color=#666666]=[/color] [color=#AA22FF]map[/color](random_line_gen, playlists)
    [color=#AA22FF][b]while[/b][/color] lines:
        [color=#AA22FF][b]for[/b][/color] playlist [color=#AA22FF][b]in[/b][/color] shuffled_playlist:
            [color=#AA22FF][b]print[/b][/color](playlist[color=#666666].[/color]next())
        lines [color=#666666]-=[/color] [color=#666666]1[/color]

[color=#AA22FF][b]if[/b][/color] __name__ [color=#666666]==[/color] [color=#BB4444]"__main__"[/color]:
    parser [color=#666666]=[/color] ArgumentParser(description[color=#666666]=[/color][color=#BB4444]"Creates a new,random playlist."[/color])
    parser[color=#666666].[/color]add_argument([color=#BB4444]"file"[/color], nargs[color=#666666]=[/color][color=#BB4444]"+"[/color], help[color=#666666]=[/color][color=#BB4444]"file1 file2 ..."[/color])
    parser[color=#666666].[/color]add_argument([color=#BB4444]"--lines"[/color], [color=#AA22FF]type[/color][color=#666666]=[/color][color=#AA22FF]int[/color], default[color=#666666]=[/color][color=#AA22FF]None[/color])

    args [color=#666666]=[/color] parser[color=#666666].[/color]parse_args()
    gen_list([color=#AA22FF]map[/color](read_m3u, args[color=#666666].[/color]file), args[color=#666666].[/color]lines)
Offtopic:
@Sleepprogger: erfreulich zu sehen einen Ordensgenossen, doch spüre den Einfluss der Dunklen Sprachen in Dir ich. Zudem Großmeister Guido mit neuen Gaben beschert uns hat :)
(sprich: der coole argparser ist schon seit paar Jährchen in der Standardbibliothek :) )
 
Schöner Code CDW.
Guyfawkes, nimm auf jeden Fall CDWs Code, der topt meinen in (fast) allen Bereichen.

[size=-2]
Ich hatte (einen Teil) meines Codes in einem Script welches zufällig einzelne Zeilen aus vielen recht grossen Dateien geholt. Da war das dann sinnvoll nicht alles im Speicher zu halten.
Hier weniger ;)
[/size]
[size=-3]
Jep, argparse muss ich mir noch angewöhnen.
[/size]

noch mehr offtopic:
Ist while counter ... in python schneller als for in xrange... ?
 
noch mehr offtopic:
Ist while counter ... in python schneller als for in xrange... ?
Kommt afaik darauf an - in PyPy entweder kein Unerschied oder while counter schneller (ich bin nicht mehr auf dem aktuellen Stand). In CPython sollte immer noch xrange im Vorteil sein. Wobei es ja meist erstmal die Ausgabe oder die Platte den Flaschenhals bilden oder man bei Datenmengen in der Praxis keinen Unterschied messen kann.

Ich habe zudem erstmal "for playlist in repeat(cycle(shufffled_pls), lines)" getippt, was irgendwie zu kompliziert aussah :). Und For-Konstrukte, bei denen der Iterator/Counter nix mit dem Body zu tun hat, missfallen mir irgendwie. Da bildete while: lines ... imho eine gute und lesbare Alternative :)
 
hey! Danke!

Lauf wie geschmiert! Geil, Geil!

jetzt brauch ich nur noch einen stream-player für meinen webspace, der playlists spielen kann. Habt Ihr Präferenzen? Probier grad ein paar durch.

lg
 
Zuletzt bearbeitet:
Zurück
Oben