|
| » myCSharp.de Diskussionsforum |
|
|
|
|
Autor
 |
|
maxE
myCSharp.de-Mitglied
Dabei seit: 27.04.2004
Beiträge: 456
Entwicklungsumgebung: SharpDevelop Herkunft: Sachsen
|
|
Audio- und Videowiedergabe mit MCI
Einleitung
Da immer wieder die Frage auftaucht, wie man denn MP3s, WMAs, Videos und CDs am einfachsten abspielen kann, habe ich mich entschlossen diesen Artikel zu schreiben.
Windows bietet ein sehr leistungsfähiges Interface zur Wiedergabe von digitalen Medien.
Diese Library ist bei jeder Windowsinstallation vorhanden.
Benötigte DLL-Importe
Um die gesamte Schnittstelle anzusprechen, brauch man nur eine C-Funktion, die wir mit Hilfe von DllImport einbinden:
C#-Code: |
[DllImport("winmm.dll")]
private static extern int mciSendString(string cmd, StringBuilder ret, int retLen, IntPtr hwnd);
|
Parameter: - cmd : Kommandostring, welches an den MCI Treiber übergeben wird (Dazu später mehr).
- ret: Enthält Rückgabewert des ausgeführten Kommandos. Vor allem für Statusabfragen wichtig.
- retLen: Länge des Rückgabewertes.
- hwnd: Fensterhandle. Einige Kommandos erzeugen Events für die Windows-Nachrichtenschleife, wenn ein notify-Flag an das Kommando gehängt wird. Man kann sich zum Beispiel benachrichtigen lassen, wenn ein Mp3-Stream beendet wurde.
Nun gut, ich habe etwas gelogen
Wir werden für die Fehlerbehandlung noch eine 2. Funktion benötigen:
C#-Code: |
[DllImport("winmm.dll")]
private static extern int mciGetErrorString(int errCode, StringBuilder errText, int errLen);
|
Diese gibt uns lokalisierte Fehlertexte für einen bestimmten Fehlercode zurück. Wie das funktioniert, kann man im Quelltext nachlesen.
Kommandostrings
Wie schon gesagt, basiert MCI auf Kommandostrings, die mit mciSendString(…) versand werden. Zu den wichtigsten Kommandos gehören:
Code: |
1:
2:
3:
4:
5:
|
open
play
stop
pause
close |
|
All diesen Kommandos können noch zusätzliche Parameter übergeben werden, die das Verhalten des Befehls genauer spezifizieren.
Beim open Kommando sieht das dann so aus:
Code: |
1:
|
open “C:\Videos\test.avi“ type mpegvideo alias VideoStream |
|
Dieser Befehl öffnet die Datei test.avi und macht sie unter dem Alias VideoStream verfügbar. Diese Aliase sind für die weitere Ansteuerung über Kommandos wichtig. So kann man die Wiedergabe mit
Code: |
1:
|
play VideoStream fullscreen |
|
beginnen und mit
Code: |
1:
|
stop VideoStream |
|
wieder anhalten.
Code: |
1:
|
close VideoStream |
|
schließt unseren Stream.
Das schöne an der Sache ist, dass diese Syntax für fast alle Medientypen mehr oder minder identisch ist. Auch MP3s und CDs lassen sich damit abspielen (siehe Quellcode).
Der zusätzliche Parameter fullscreen im Play-Kommando ist optional und entscheidet nur darüber, ob das Video im Vollbildmodus abgespielt wird oder nicht.
Für Audio-CDs kann man auch die CD Klappe öffnen und schließen. Dazu sendet man einfach folgende Kommandos:
Code: |
1:
|
set cdaudio door open |
|
und
Code: |
1:
|
set cdaudio door closed |
|
Alle Befehlsstrings zu behandeln, würde hier wohl den Rahmen sprengen. Auf MSDN werden sie alle ausführlich beschrieben:
http://msdn.microsoft.com/library/defaul...i_reference.asp
Beispielprogramm
Ich habe für diesen Artikel einen kleinen Multimedia-Player geschrieben, der die Verwendung der MCI-Bibliothek demonstriert:
// Update (18.06.05): Habe einen Bug im Programm entfernt. Der Player sollte jetzt besser mit aufretenden Fehlern umgehen (z.B. wenn keine CD eingelegt ist)
|
|
29.04.2005 23:14
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
| Zwischen diesen beiden Beiträgen liegen mehr als 2 Monate. |
dr4g0n76
myCSharp.de-Poweruser/ Experte
Dabei seit: 07.07.2005
Beiträge: 2.705
Entwicklungsumgebung: SharpDevelop/VS.NET Herkunft: Deutschland
|
|
Ja damit kann man vor allem auch gut CD-Laufwerk auf/zu machen und z.B. den Motor anhalten. ;-)
|
|
08.07.2005 11:21
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
| Zwischen diesen beiden Beiträgen liegen mehr als 2 Monate. |
alf468
myCSharp.de-Mitglied
Dabei seit: 20.02.2005
Beiträge: 196
Entwicklungsumgebung: Visual Studio .NET 2005
|
|
Ich möchte gerne alle mp3s aus einem Ordner abspielen.
C#-Code: |
public void getlieder()
{
String[] files=Directory.GetFiles(Data.musik,"*.mp3");
foreach(string name in files)
{
if(this._play==true)
{
this.name=name;
string cmd = "open \"" + name + "\" type " + "mpegvideo" + " alias \"" + name + "\"";
int errCode = mciSendString(cmd, null, 0, IntPtr.Zero);
CheckError(errCode);
this.SetTimeFormat("m");
String time=this.GetLength();
this.Play(time);
System.Threading.Thread.Sleep(int.Parse(time));
}
else
{
break;
}
}
}
|
So werden zwar alle Lieder abgespielt aber es dauert immer etwas bis ein neues Lied anfängt.
Habt ihr bessere Vorschläge?
PS.: Der Musikplayer läuft als Thread neben den eigentlichen Programm.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von alf468 am 25.09.2005 15:06.
|
|
25.09.2005 15:06
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
SGT_BOB
myCSharp.de-Mitglied
Dabei seit: 10.03.2005
Beiträge: 125
Entwicklungsumgebung: SharpDevelop v2.2.0; MSVS2005 Herkunft: Aachen
|
|
Hallo Leute.
Ich hab ebenfalls eine Frage.
Ich setze mit
C#-Code: |
mciCommand = "set \"" + currentTrack + "\" time format ms";
mciErrorCode = mciSendString(mciCommand, null, 0, IntPtr.Zero);
|
das Zeitformat auf Millisekunden
und lese mit
C#-Code: |
private string GetLength()
{
Console.WriteLine(currentTrack);
StringBuilder buffer = new StringBuilder(256);
mciCommand = "status \"" + currentTrack + "\" length";
mciErrorCode = mciSendString(mciCommand, buffer, 256, IntPtr.Zero);
return buffer.ToString();
}
|
die Länge des Tracks ein.
Leider ist der zurückgegebene String leer ("").
Weiß jemand wieso? Ich hab es genau wie in dem Beispiel im Anhang. Dort funktioniert es auch wunderbar.
Was mach ich falsch?
Mfg SGT_BOB
|
|
10.10.2005 00:18
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
SGT_BOB
myCSharp.de-Mitglied
Dabei seit: 10.03.2005
Beiträge: 125
Entwicklungsumgebung: SharpDevelop v2.2.0; MSVS2005 Herkunft: Aachen
|
|
Hi maxE.
Erst mal danke für die Antwort. Aber dein Beispiel funktioniert ja. Ich öffne das selbe MP3-File. Beim Beispiel-Programm funztes, bei meinem bekomme ich einen Fehlercode (263, glaub ich) zurück.
Noch irgendeine Ahnung?
Mfg SGT_BOB
EDIT:
Hat sich gerade erledigt. Ich weiß zwar nicht wieso, aber ich habe es jetzt geschafft. 
Danke trotzdem.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von SGT_BOB am 11.10.2005 23:35.
|
|
11.10.2005 23:08
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
lex
myCSharp.de-Mitglied
Dabei seit: 14.12.2004
Beiträge: 113
Entwicklungsumgebung: Visual Studio 2005 Herkunft: Niedersachsen
|
|
moin,
hab dazu noch mal eine frage, kennt sich hier wer zufällig mit der Quartz.dll aus?
hätte da noch ein paar fragen und würde mich übner hilfe sehr freuen!
1.) ich kann 2 stuecke zur gleichen Zeit abspielen, sehr ungünstig!
2.) pause hat ne zeitverzögerung von knapp 10sec, viel zu lange!!!
|
|
02.11.2005 11:50
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
| Zwischen diesen beiden Beiträgen liegen mehr als 8 Monate. |
Slowflyer
myCSharp.de-Mitglied
Dabei seit: 21.07.2006
Beiträge: 1
Entwicklungsumgebung: Sharpdevelop Herkunft: NRW
|
|
Hallo,
mit Interesse habe ich diesen Artikel gelesen und danch gleich ausprobiert. Ich kann auch Videos abspielen. nun stoße ich jedoch auf ein Problem: die Videos werden in einem separaten Fenster geöffnet. Ich hätte aber gerne, dass das Video in meinem Hauptfenster (vielleicht in irgensdeinem Control) in einer definierten Größe abgespielt wird. Wie stellt man soetwas an?
Gruß, Slowflyer
|
|
21.07.2006 10:17
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
SkySurfer
myCSharp.de-Mitglied
Dabei seit: 08.08.2006
Beiträge: 298
Entwicklungsumgebung: VS 2005 / 2008 Herkunft: bei Stuttgart
|
|
Hi,
du kannst dem MCI ein Handle von z.B. einer Picturebox übergeben in der die Wiedergabe dann ablaufen soll.
C#-Code: |
[DllImport("winmm.dll")]
private static extern int mciSendString(string cmd, StringBuilder ret, int retLen, IntPtr hwnd);
|
einfach dem IntPtr hwnd z.B. ein PictureBox.handle übergeben anstatt eines IntPtr.Zero
Gruß SkySurfer
|
|
08.08.2006 09:31
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
wmieh
myCSharp.de-Mitglied
Dabei seit: 16.08.2006
Beiträge: 3
|
|
Sehr guter Beitrag, hat mich wirklich weiter gebracht.
Ich habe allerdings noch nicht herausgefunden, wie ich abfragen kann wann ein Titel zuende gespielt wurde. Vielleicht kann mir da jemand helfen...danke im voraus.
|
|
18.08.2006 11:30
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
| Zwischen diesen beiden Beiträgen liegen mehr als 4 Monate. |
Seikilos
myCSharp.de-Mitglied
Dabei seit: 19.10.2006
Beiträge: 737
Entwicklungsumgebung: VS 2008
|
|
Hallo,
mir geht es genauso, ich suche ein Event oder ähnliches, was mir sagt, ob das Lied gerade zu ende gespielt worden ist, oder nicht.
Im Moment sehe ich da nur die Möglichkeit zu vergleichen ob getcurrentPos == getLength ist
|
|
28.12.2006 17:38
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
| Zwischen diesen beiden Beiträgen liegen mehr als 6 Monate. |
zeax
myCSharp.de-Mitglied
Dabei seit: 05.07.2007
Beiträge: 38
|
|
ich wollte fragen wie ich statt einer datei einfach den teil der zur zeit gerade über meine soundkarte ausgegeben wird. abgreifen kann um ihn dann so über das netzwerk zu verschicken und an einem anderen rechner mithilfe von mci abspielen kann
gruß zeax
|
|
05.07.2007 16:20
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Durin-V
myCSharp.de-Mitglied
Dabei seit: 07.05.2007
Beiträge: 43
|
|
Hi Leute,
zu dem Pointer mit der PictureBox.
Ich hab die Funktionen der MCI aus deinem Beispiel Code direkt übernommen. Das einzige was ich daran geändert habe ist das dich dem ganzen noch einen Konstruktor spendiert habe bei dem ich dann den IntPtr einer Picture Box übergebe der dann in der Klasse als private Variable gespeichert wird.
Außerdem habe ich alle IntPtr.Zero durch den Variablennamen ersetzt. Doch wenn ich nun mit meiner Funktion eine Video ansehen will, öffnet er mir dieses immer noch in einem separatem Fenster.
Woran kann das liegen?
Gruß
Durin-V
|
|
17.07.2007 23:32
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
TheBrainiac
myCSharp.de-Mitglied
Dabei seit: 17.12.2006
Beiträge: 767
Entwicklungsumgebung: VS 2010 Prof. Herkunft: /dev/null
|
|
Du musst das Handle der PictureBox (oder Form oder sonstwas) im CommandString mit übergeben :
C#-Code: |
mciSendString("open \"" + name + "\" type mpegvideo alias \"" + name + "\" parent " + pictureBox1.Handle.ToInt32().ToString() + " style child", null, 0, IntPtr.Zero);
|
Nun zu meiner Frage: Wie findet man die Originalgröße des Videos heraus?
Gruß, Christian.
|
|
23.07.2007 23:14
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
confused
myCSharp.de-Mitglied
Dabei seit: 25.03.2004
Beiträge: 62
|
|
Hallo!
Ich habe ein Problem mit der Wiedergabe...wenn ich das Beispielprogramm verwende funktionniert es ohne Probleme, kopiere ich allerdings die SimpleAudioVideoPlayback.cs in ein anderes Projekt und erstelle dort eine neue Instanz und rufe Open() auf, bekomme ich einen Fehler:
Unbekanntes Problem beim Laden des angegebenen Gerätetreibers.
C#-Code: |
static void Main(string[] args)
{
MCIPlayback m = new MCIPlayback();
m.Open(@"C:\c.mp3", "mpegvideo");
}
|
Weiß jemand, woran das liegen könnte? Hat es vielleicht damit zu tun, dass es einmal eine Windowsapplikation ist, und das andere mal liegt die Datei in einer DLL und wird von obiger Main aufgerufen?
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von confused am 27.07.2007 23:01.
|
|
27.07.2007 21:19
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
confused
myCSharp.de-Mitglied
Dabei seit: 25.03.2004
Beiträge: 62
|
|
Ok, ich habe den Fehler gefunden:
Aus irgendeinem Grund muss das Programm, das ausgeführt wird und diese MCI-Sachen aufruft mit [STAThread] gekennzeichnet sein.
Kriegt man dieses Problem noch in den Griff?! Ansonsten bin ich soweit fertig!
|
|
28.07.2007 18:29
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
| Zwischen diesen beiden Beiträgen liegt mehr als ein Monat. |
ForceDragonX
myCSharp.de-Mitglied
Dabei seit: 09.06.2007
Beiträge: 17
Entwicklungsumgebung: Visual C# 2005 Express Edition
|
|
| Zitat: |
Original von Schamese
Nun zu meiner Frage: Wie findet man die Originalgröße des Videos heraus?
Gruß, Christian. |
Würde mich auch interessieren.
Aber was ich auch wissen will: Kann man das Video 'verkleinern', sodass, wenn man das Form mit der Picturebox (die das Video anzeigt) verkleinert, das Video nicht einfach abgeschnitten wird, sondern sich mit verkleinert.
|
|
20.09.2007 15:35
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
cemizm
myCSharp.de-Mitglied
Dabei seit: 19.07.2007
Beiträge: 11
Entwicklungsumgebung: Sharpdevelop Herkunft: Bielefeld
|
|
Dock doch einfach mal die Picturebox in der Form so das die Picutrebox immer die ganze Form füllt.
Mfg
|
|
21.09.2007 08:38
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
| Zwischen diesen beiden Beiträgen liegen mehr als 2 Monate. |
Hunv
myCSharp.de-Mitglied
Dabei seit: 08.08.2005
Beiträge: 171
Entwicklungsumgebung: VS 2010, Win8 64Bit
|
|
| Zitat: |
Original von confused
Ok, ich habe den Fehler gefunden:
Aus irgendeinem Grund muss das Programm, das ausgeführt wird und diese MCI-Sachen aufruft mit [STAThread] gekennzeichnet sein.
Kriegt man dieses Problem noch in den Griff?! Ansonsten bin ich soweit fertig!
|
Danke! Hat mir echt weitergehofen!
Edit:
Achja: und kann man die Lautstärke verändern oder muss das über den Wave-Kanal erledigt werden?
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Hunv am 27.11.2007 20:10.
|
|
27.11.2007 19:37
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Hunv
myCSharp.de-Mitglied
Dabei seit: 08.08.2005
Beiträge: 171
Entwicklungsumgebung: VS 2010, Win8 64Bit
|
|
Aaalso:
Man kann die Lautstärke verändern.
Die MCI-SendStrings sind wie folgt:
Linker Audiokanal:
mciSendString(string.Concat("setaudio MediaFile left volume to ", value), null, 0, 0);
Rechter Audiokanal:
mciSendString(string.Concat("setaudio MediaFile right volume to ", value), null, 0, 0);
Master Kanal:
mciSendString(string.Concat("setaudio MediaFile volume to ", value), null, 0, 0);
value hat dabei einen Wert von 0 bis 1000
Zusätzlich kann man angeblich noch Bass und Treble verändern, aber bei mir funktioniert es nicht. Trotzdem hier die Strings dafür (auch hier hat Value einen Wert von 0 bis 1000):
mciSendString(string.Concat("setaudio MediaFile bass to ", value), null, 0, 0);
mciSendString(string.Concat("setaudio MediaFile treble to ", value), null, 0, 0);
|
|
30.11.2007 12:12
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Wanginator
myCSharp.de-Mitglied
Dabei seit: 28.11.2007
Beiträge: 33
Herkunft: Berlin
|
|
Ist die winmm.dll standardmäßig bei allen Windows-Versionen (ab 98) nach der Neuinstallation mit dabei? Muss wissen ob mciSendString universell einsetzbar ist für versch. OS-Versionen
|
|
13.12.2007 11:48
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
TheBrainiac
myCSharp.de-Mitglied
Dabei seit: 17.12.2006
Beiträge: 767
Entwicklungsumgebung: VS 2010 Prof. Herkunft: /dev/null
|
|
MCI gibt es imho seit Win3.1x. Man muss nur die Audiocodecs nachinstallieren, die man braucht.
Gruß, Christian.
|
|
13.12.2007 20:45
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
| Zwischen diesen beiden Beiträgen liegt mehr als ein Jahr. |
TimeOver
myCSharp.de-Mitglied
Dabei seit: 23.03.2009
Beiträge: 1
Entwicklungsumgebung: Visual C# 2008 Express Edition Herkunft: Bayern
|
|
Hallo,
dieser Thread ist zwar schon etwas älter, ich habe aber trotzdem noch eine Frage dazu. Und zwar möchte ich bestimmte Frames des Videos als Bitmap, Color-Array oder vergleichbares bekommen, diese bearbeiten und wieder in ein video(avi) speichern. Auch den Sound möchte ich entfernen und wieder hinzufügen können. Ist dies mit MCI möglich oder kennt ihr noch andere Möglichkeiten?
Ich hoffe sehr, dass mir jemand weiterhelfen kann, ich google nämlich schon seit längerem und das einzige vernünftige, was ich bekommen habe ist das hier:
http://www.codeproject.com/KB/audio-vide...ilewrapper.aspx
Leider gab es hier aber zu oft AVIs, die nicht geöffnet werden konnten.
mfg
TimeOver
|
|
23.03.2009 13:51
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
FZelle
myCSharp.de-Poweruser/ Experte
Dabei seit: 23.04.2004
Beiträge: 8.478
|
|
Nein, MCI ist nicht für Videobearbeitung gedacht.
Wenn Du dir mal Projekte wie VirtualDup und CO anschaust, wirst Du feststellen,
das das alles nicht wirklich einfach ist.
|
|
23.03.2009 14:17
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
|