Laden...

C# MP3 Player ohne DLL

Erstellt von AyrA vor 11 Jahren Letzter Beitrag vor 11 Jahren 12.248 Views
AyrA Themenstarter:in
60 Beiträge seit 2010
vor 11 Jahren
C# MP3 Player ohne DLL

Beschreibung:

Es handelt sich hier um einen MP3 Player. Dieser wurde komplett in C# geschrieben und besitzt folgende interessante Eigenschaften:

  1. Keine DLL. Die Anwendung ist nicht von Drittherstellern abhängig (LAME.DLL, etc)
  2. Keine WinAPI oder unmanaged Code. Alles ist in reinem C# geschrieben und greift nicht auf native Code Resourcen zurück (z.B. winmm.dll)

Screenshot:
siehe Anhang

Wissenswerte Informationen:

.NET Version: 2.0

Das Programm spielt auch weitere Formate ab (wav, wma, ogg). Dies ist primär abhängig vom installierten Codec, dadurch lassen sich sogar Audio Tracks von Videodateien abspielen. Dateierweiterungen kann man mit dem Edit Button konfigurieren

Tastatursteuerung:
[ESC] Beenden
[->] 3 Sekunden vor
[<-] 3 Sekunden zurück
[^] Lauter
[v] Leiser
[SPACE] pause
[HOME] Song Neustart (auch Taste [R] möglich)

Single Instance mit Inter Process Communication.
Läuft bereits eine instanz, wird die bestehende gezeigt und keine neue geladen. Versucht man mit der neuen Instanz eine Datei zu öffnen, wird sie stattdessen in der ersten geöffnet.

Startparameter support. Das Programm kann direkt mit einer MP3 Datei geöffnet werden.

Drag & Drop support. Einfach eine Datei in das Viereck ziehen um den Abspielvorgan zu starten.

Songs werden im Repeat Modus gespielt.

Die Progress Bar ändert die Farbe von Grün (0%) über Gelb (50%) nach Rot (100%). Dies ist kein Eigenes Control sondern eine standard Progressbar

========

Das Programm wurde von mir geschrieben um schnell Musikdateien vorhören zu können, ohne einen riesen Player zu laden. Deswegen ist z.B. kein Playlist Support vorhanden. Die Anwendung muss möglichst schnell starten und ist deswegen auch relativ klein (ca. 28 KB).
Am effektivsten arbeitet das Tool wenn ein Kontextmenu Handler registriert wird.

Bin gerne für Erweiterungsvorschläge offen.


So wird ein Kontextmenu handler registriert, wer einen haben will:
[list]
[*]Registry Editor öffnen ([WIN]+[R], [B]REGEDIT.EXE[/B])
[*]navigieren nach [B]HKEY_CLASSES_ROOT\*\shell[/B]
[*]Hier einen Schlüssel durch Rechtsklick auf [B]shell[/B] anlegen (Name: [B]QuickPlay[/B])
[*]Diesem Schlüssel nun rechts den Standardwert setzen. (Dieser Text wird im Kontextmenü gezeigt). z.B: [B]&Quick Play[/B] (das & ist beabsichtigt und macht, dass im Kontextmenü das Q unterstrichen ist und der Punkt über die Q Taste zugänglich wird)
[*]Einen Unterschlüssel mit dem Namen [B]command[/B] erstellen
[*]Den Standardwert setzen auf (inkl Anführungszeichen): [B]"PFAD\ZUR.EXE" "%1"[/B], natürlich müsst ihr hier den Pfad anpassen.
[*]Registry Editor schliessen. Änderungen sind sofort wirksam
[/list]
Das Entfernen des ersten angelegten Schlüssels (in Punkt 3) entfernt den Kontextmenu handler.

Die Anwendung ist digital signiert um unautorisierte Änderungen zu verhindern.

Wenn jemand Interesse an einer DLL zum Einbinden hat stelle ich gerne eine zur Verfügung

**:::

AyrA Themenstarter:in
60 Beiträge seit 2010
vor 11 Jahren
Screen 2

Screenshot 2:
Einstellungsfenster

**:::

AyrA Themenstarter:in
60 Beiträge seit 2010
vor 11 Jahren
Screen 1:

Screenshot Hauptfenster.

Das ist echt dumm, hierfür 3 Posts erstellen zu müssen.

**:::

16.807 Beiträge seit 2008
vor 11 Jahren

Hallo,

danke für die Bereitstellung Deiner Entwicklung.
Jedoch wird vermutlich die Interesse an der ausführbaren Anwendung nicht wirklich hoch sein, da man quasi nichts wirklich damit anfangen kann.

Das Bereitstellen einer DLL (Lizenzbedingungen für .NET-Komponenten und C#-Snippets auf myCSharp.de) wäre also sicherlich interessanter und eher was für die hiesige Zielgruppe.

Dass pro Beitrag nur ein Anhang möglich ist; das muss man einfach akzeptieren.
Mehrere Beiträge diesbezüglich sind legitim. Siehe auch [Hinweis] Wie poste ich richtig? 6.1

C
12 Beiträge seit 2006
vor 11 Jahren

Es wäre interessant zu erfahren wie du das eigentlich genau gemacht hast. Vielleicht könntest du das genauer erklären und eine DLL zur Verfügung stellen. Der Hammer wäre natürlich der Quellcode... 😁

309 Beiträge seit 2008
vor 11 Jahren

Du solltest noch erwähnen das du DirectX benutzt um die Audio-Dateien abzuspielen, hier auf meinem alten Laptop noch mit WinXP (ohne DirectX), ist mir gleich eine Riesen Exception um die Ohren geflogen.

Aber die Idee des Programms ist ganz nett. 👍

using System;class H{static string z(char[]c){string r="";for(int x=0;x<(677%666);x++)r+=c[
x];return r;}static void Main(){int[]c={798,218,229,592,232,274,813,585,229,842,275};char[]
b=new char[11];for(int p=0;p<((59%12));p++)b[p]=(char)(c[p]%121);Console.WriteLine(z(b));}}

F
10.010 Beiträge seit 2004
vor 11 Jahren

Und das man über eine Datei ft.txt im Anwendungsverzeichnis die erlaubten Extensions verwalten kann, kannst du auch schreiben.

AyrA Themenstarter:in
60 Beiträge seit 2010
vor 11 Jahren

Kompilierte DLL im Anhang

Einmal als AnyCPU kompiliert und einmal als x86.

Der Hammer wäre natürlich der Quellcode...

OK. Source der DLL ist ziemlich einfach und lediglich eine einzlne Klasse:

using Microsoft.DirectX.AudioVideoPlayback;
using System.Collections.Generic;
using System;
using System.Threading;
using System.IO;

namespace AyrA.Media
{
    /// <summary>
    /// This class Provides simple Audio Playback.
    /// Formats depend on Codecs
    /// </summary>
    public class QuickPlayer : IDisposable
    {
        private bool disposed = false;
        private Audio snd;

        /// <summary>
        /// Returns the Position in Seconds of the current Playback
        /// </summary>
        public double Position
        {
            get
            {
                return snd.CurrentPosition;
            }
            set
            {
                if (value <= snd.Duration && value>=0)
                {
                    snd.CurrentPosition = value;
                }
            }
        }

        /// <summary>
        /// Returns the Length of the current Song
        /// </summary>
        public double Length
        {
            get
            {
                try
                {
                    return snd.Duration;
                }
                catch
                {
                    return -1.0;
                }
            }
        }

        /// <summary>
        /// Returns current Volume Min: -10000, Max: 0
        /// </summary>
        public int Volume
        {
            get
            {
                try
                {
                    return snd.Volume;
                }
                catch
                {
                    return 0;
                }
            }
            set
            {
                if (value <= 0 && value >= -10000)
                {
                    snd.Volume = value;
                }
            }
        }

        /// <summary>
        /// Stops Playback and disposes the Component
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Disposes the Component
        /// </summary>
        /// <param name="disposing"></param>
        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    snd.Stop();
                    snd.Dispose();
                }
                //Free your own state (unmanaged objects).
                //Set large fields to null.
                disposed = true;
            }
        }

        /// <summary>
        /// Disposes the Component
        /// </summary>
        ~QuickPlayer()
        {
            //Simply call Dispose(false).
            Dispose (false);
        }

        /// <summary>
        /// Initializes a new Quick Player
        /// </summary>
        public QuickPlayer()
        {
        }

        /// <summary>
        /// Initializes a new Quick Player and starts Playback
        /// </summary>
        /// <param name="File">File to play</param>
        public QuickPlayer(string File)
        {
            Play(File);
        }

        /// <summary>
        /// Seeks forward or backward
        /// </summary>
        /// <param name="d">Seconds to seek</param>
        public void Seek(double d)
        {
            if (snd.CurrentPosition + d < snd.Duration && snd.CurrentPosition + d > 0)
            {
                snd.CurrentPosition += d;
            }
        }

        /// <summary>
        /// Plays specified File, cancelling an existing Playback
        /// </summary>
        /// <param name="File">File to play</param>
        public void Play(string File)
        {
            if (snd != null)
            {
                lock (snd)
                {
                    int vol = snd.Volume;
                    try
                    {
                        snd.Open(File, true);
                    }
                    catch
                    {
                    }
                    snd.Volume = vol;
                }
            }
            else
            {
                snd = new Audio(File);
                snd.Play();
            }
        }

        /// <summary>
        /// Stops current Playback
        /// </summary>
        public void Stop()
        {
            snd.Stop();
        }

        /// <summary>
        /// Pauses or resumes Playback
        /// </summary>
        public void Pause()
        {
            if (snd.Paused)
            {
                snd.Play();
            }
            else
            {
                snd.Pause();
            }
        }

        /// <summary>
        /// Restarts current Song
        /// </summary>
        public void Restart()
        {
            snd.SeekCurrentPosition(0.0, SeekPositionFlags.AbsolutePositioning);
        }
    }
}

Referenz auf die Microsoft.DirectX.AudioVideoPlayback.DLL ist notwendig!

hier auf meinem alten Laptop noch mit WinXP (ohne DirectX), ist mir gleich eine Riesen Exception um die Ohren geflogen

Interessant, als ich auf meinem Laptop das .NET 2.0 Package installiert hatte kamen die DirectX DLLs gleich mit. auf meinem alten PC mit Windows ME funktioniert es auch.

Und das man über eine Datei ft.txt im Anwendungsverzeichnis die erlaubten Extensions verwalten kann, kannst du auch schreiben.

Ist aber nicht sehr bequem, da du das Programm neu laden musst, damit es Wirkung zeigt. Grundsätzlich halte ich dies nicht für erwähnenswert, sofern im Programm eine Funktion zur Editierung vorhanden ist, aber das ist Ansichtssache

**:::

Q
49 Beiträge seit 2010
vor 11 Jahren

schade, ich dacht hier wäre irgendwie ne eigene mp3 implementierung am werk...

AyrA Themenstarter:in
60 Beiträge seit 2010
vor 11 Jahren

schade, ich dacht hier wäre irgendwie ne eigene mp3 implementierung am werk...

Das eigene implementeren eines MP3 decoders könnte lizenztechnische Probleme nach sich ziehen. MP3 ist kein freies Format und (wenn ich mich nicht täusche) sogar patentiert. Nur weil die MPEG Group keine Rechtlichen Schritte gegen nicht lizenzierte en-/decoder unternimmt heisst das nicht, dass sie es nie tun werden. Es gibt viele MP3 Decoder source Codes in C und C++, die man nach C# porten könnte, wenn man dringend einen braucht. Des weiteren kann man Patente im Internet einsehen und daher auch den Aufbau des Codecs, wenn man einen eigenen Decoder schreiben möchte. Ich wollte jedoch eine Lösung, die mich nicht vor Lizenzprobleme stellt. Durch verwenden des Microsoft internen DirectX Decoders ist Microsoft für die Lizenzierung zuständig, da sie über die EULA die DirectX Managed Komponente an mich weiter Lizenziert.
Der DirectX Versuch von mir lädt einiges schneller als der Media Player Core. Habe damit mittlerweile schon ein komplettes Webradio mit HTTP stream realisiert. Für den Media Player Ansatz müsste man auf einem Windows Server diverse zusatzdienste installieren (Windows Vista Desktop Experience) was mir etwas viel ist, nur um die WMP API nutzen zu können. Die managed DLLs von DirectX hingegen sind nur wenige MB gross.

**:::

16.807 Beiträge seit 2008
vor 11 Jahren

Eine EULA betrifft den End User.
Ob die Lizenz, die Microsoft hier "weiterreicht" und rechtlich wasserdicht ist, sollte man bei rechtlichen Bedenken immer durch einen spezialisierten Anwalt prüfen lassen.

Fest steht aber, dass ein Entwickler kein End User ist.
"An Dich weiter lizenziert" ist womöglich rechtlich der falsche Ausdruck.

AyrA Themenstarter:in
60 Beiträge seit 2010
vor 11 Jahren

Eine EULA betrifft den End User.

End User des DirectX SDKs ist der Entwickler, der Nutzer hat lediglich die Runtime.
Die Lizenzen der Runtime sind hier: DirectX 9.0c - End-User EULAs

Ob die Lizenz, die Microsoft hier "weiterreicht" und rechtlich wasserdicht ist, sollte man bei rechtlichen Bedenken immer durch einen spezialisierten Anwalt prüfen lassen.

Falsch, für die Korrektheit einer Lizenz ist der Aussteller verantwortlich. Als End Nutzer habe ich das Recht diese zu prüfen, nicht aber die Pflicht. Wenn du an eine Lizenz kommst, darfst du davon ausgehen, dass diese OK ist. Sollte Microsoft eine Komponente in einer EULA an einen Nutzer weiterlizenzieren und dürfte das nicht, so ist Microsoft haftbar. Als End Nutzer kenne ich ja die Lizenzbedingungen zwischen Microsoft und dessen zulieferern nicht. Bei DirectX besteht die Gefahr zwar nicht, ist aber nie schlecht zu wissen.

Fest steht aber, dass ein Entwickler kein End User ist.

Vom Entwicker SDK schon.

"An Dich weiter lizenziert" ist womöglich rechtlich der falsche Ausdruck.

Relizenzierung wäre glaube ich der richtige Ausdruck.

**:::

Hinweis von herbivore vor 11 Jahren

Weiter ins Detail sollten wir hinsichtlich der rechtlichen Fragen nicht gehen, zumal nicht mal Anhaltspunkt für eine mögliche Rechtswidrigkeit vorliegen.