Audio-CD auslesen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
ob auf einem System ein optisches Laufwerk zur Verfügung steht und wenn ja, welche Bezeichnung das Laufwerk hat?
Windows, Linux oder MacOS?

Gruß, noisefloor
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

Hallo @noisefloor:

Sorry, darauf hätte ich natürlich eingehen müssen. Für mich selbst wäre es Windows, aber an Linux und MacOS wäre ich auch interessiert.

MfG, kodela
BlackJack

@Kodela: Unter Linux könnte man den `udisks-daemon` via `dbus` befragen:

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf-8
from __future__ import absolute_import, division, print_function
from functools import partial
import dbus

UDISKS_SERVICE = UDISKS_IFACE = 'org.freedesktop.UDisks'
UDISKS_DEVICE_IFACE = UDISKS_IFACE + '.Device'


def main():
    bus = dbus.SystemBus()
    udisks = bus.get_object(UDISKS_SERVICE, '/org/freedesktop/UDisks')
    for path in udisks.EnumerateDevices(dbus_interface=UDISKS_IFACE):
        device = bus.get_object(UDISKS_SERVICE, path)
        properties_iface = dbus.Interface(device, dbus.PROPERTIES_IFACE)
        device_get = partial(properties_iface.Get, UDISKS_DEVICE_IFACE)
        if device_get('DeviceIsDrive'):
            compatible_media = device_get('DriveMediaCompatibility')
            if any(media.startswith('optical') for media in compatible_media):
                print(device_get('DeviceFile'), ':', device_get('DriveModel'))


if __name__ == '__main__':
    main()
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

Danke @BlackJack

und einen guten Rutsch ins Neue Jahr.

kodela
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

Hallo,

ich habe nun etwas gebastelt, womit im System alle Laufwerke abgefragt und darauf überprüft werden, ob es sich um ein optisches Laufwerk mit eingelegter Audio-CD handelt. Hier meine Lösung:

Code: Alles auswählen

# coding=utf-8

import os
from string import ascii_uppercase

gefunden = False
for c in ascii_uppercase:
    path = c + ':'
    try:
        props = os.stat(path)
    except WindowsError:
        continue
    if os.path.isdir(path):
        props = os.stat(path)
        if props[6] == 0:
            # Größe des Objekts in Bytes - bei Audio CDs: 0
            print 'Im Laufwerk ' + path + ' ist eine Audio-CD eingelegt.'
            gefunden = True
if not gefunden:
    print 'Es wurde kein Laufwerk mit eingelegter Audio-CD gefunden.'
Gehe ich richtig in der Annahme, dass diese Lösung auch unter Linux und OS X funktioniert?

MfG, kodela
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

kodela hat geschrieben:Gehe ich richtig in der Annahme, dass diese Lösung auch unter Linux und OS X funktioniert?
Nein. Unter Linux und OSX existieren schon mal keine Laufwerksbuchstaben. Und einen `WindowsError` natürlich auch nicht, sind ja nicht Windows... :wink:
Zuletzt geändert von mutetella am Freitag 1. Januar 2016, 20:00, insgesamt 1-mal geändert.
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@kodela: Unixoide System haben keine Laufwerksbuchstaben. Ich bezweifle sogar, dass Deine Lösung unter Windows robust funktioniert.
BlackJack

@kodela: Weder Linux noch MacOS kennen so etwas wie Laufwerksbuchstaben. Und auch bei Windows dürfte der Test auf ”Audio-CD” nicht zuverlässig mit der Grösse 0 abzutesten sein. Anstelle der magischen 6 würde ich da auch eher das Attribut `st_size` verwenden.

Ich denke nicht das es eine plattformübergreifende Lösung gibt, man wird schon für jedes System etwas eigenes schreiben müssen, und dabei dann auch die vom System angebotenen konkreten Schnittstellen verwenden statt über allgemeine Eigenschaften zu ”raten” ob es sich um ein optisches Laufwerk handelt und ob eine Audio-CD eingelegt ist.
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

Danke für Eure Hinweise!

@mutetella: Das mit " except WindowsError" ist natürlich Quatsch. Ursprünglich hatte ich nur "except" gesetzt und jetzt auch wieder. Damit funktioniert es ja auch einwandfrei. "WindowsError" habe ich nur gesetzt, weil bei einer Fehlermeldung ein "WindowsError" angezeigt wurde. Mein Gedanke war, unter einem anderen OS könnte der Fehler ja eine andere Bezeichnung habe, aber ansonsten die Ereignisbehandlung im Prinzip genau so funktionieren. Mit Linux und OSX habe ich noch nie gearbeitet, daher meine naive Frage.

@Sirius3 & @BlackJack: Ihr bezweifelt, dass meine Lösung robust funktioniert. Das verstehe ich, denn auch ich habe Bedenken. Allerdings habe ich den Code unter Windows 7 und Vista mit drei verschiedenen Laufwerken (auf jedem Rechner mit dem internen Laufwerk und einem externen) getestet.

Bei allen Tests bekam ich für die Objektgröße (os.stat(path).st_size)
- ohne eine Disk einen Fehler,
- mit einer Daten-Disk, einer Video-DVD und einer Blu-ray Disk einen Wert größer Null
- und eine Audio-CD den Wert Null.

Zwischenzeitlich fand ich nun allerdings zwei Daten-DVDs mit CDFS-Formatierung, bei denen der Wert für os.stat(path).st_size ebenfalls Null ist. Bei beiden ist allerdings der Wert für os.stat(path).st_mtime kleiner Null, so dass ich mit folgendem Code bisher keine Disk mehr fand, die als Audio-CD identifiziert würde, ohne es zu sein.

Code: Alles auswählen

# coding=utf-8

import os
from string import ascii_uppercase

gefunden = False
for c in ascii_uppercase:
    path = c + ':'
    try:
        props = os.stat(path)
    except:
        continue
    if os.path.isdir(path):
        props = os.stat(path)
        if props.st_size == 0 and props.st_mtime < 0:
            print 'Im Laufwerk ' + path + ' ist eine Audio-CD eingelegt.'
            gefunden = True
if not gefunden:
    print 'Es wurde kein Laufwerk mit eingelegter Audio-CD gefunden.'
Umgekehrt fand ich auch keine Audio-CD, die nicht erkannt würde.

@BlackJack: Vom System angebotene konkrete Schnittstellen wären mir auch lieber gewesen, nur habe ich nichts gefunden, wie dies über Python zu erreichen ist. Ich bin mir sicher, dass es geht, das "Wie" hat sich mir nur nicht erschlossen.
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

Im vorstehenden Beitrag muss der Absatz vor dem Codeblock richtig lauten:

Zwischenzeitlich fand ich nun allerdings zwei Daten-DVDs mit CDFS-Formatierung, bei denen der Wert für os.stat(path).st_size ebenfalls Null ist. Ich fand allerdings eine weitere Besonderheit von Audio CDs. Der Wert für os.stat(path).st_mtime ist bei allen von mir überprüften Audio CDs kleiner Null, so dass ich mit folgendem Code bisher keine Daten-DVD mehr fand, die als Audio-CD identifiziert würde, ohne es zu sein.
BlackJack

@kodela: Da jetzt weiter herumzuraten welche Eigenschaften von einer Audio-CD per `stat()` ermittelt werden könnten was sie von anderen Laufwerken/Datenträgern unterscheiden könnte macht IMHO keinen Sinn. Das mit der `st_mtime` kleiner Null würde ich als Zufall einstufen. Umgekehrt können auf einer Audio-CD auch zusätzlich Daten drauf sein, womit der „Grösse gleich Null“-Test nicht zuverlässig ist.

Mit verschiedenen *CD*-Laufwerken zu testen macht wahrscheinlich keinen Sinn, denn welche Werte da von `stat()` kommen hängt nicht von der Hardware ab. Es könnte aber durchaus andere Hardware geben die bei Deinen Tests zu falsch positivem Test führen könnte.

Die Windows-API kann man mit dem `win32`-Package und/oder über das `ctypes`-Modul ansprechen.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

kodela hat geschrieben:Ursprünglich hatte ich nur "except" gesetzt und jetzt auch wieder.
Das solltest Du grundsätzlich nicht machen. Ein ``try... except...`` Block sollte nicht alle möglichen Fehler behandeln sondern explizit nur die Fehler, bei denen Du dann auch weißt, was bei ihrem Auftreten zu tun ist.
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

@BlackJack, @mutetella,

Danke für Eure Hinweise.
Antworten