Hallo,
ich übergebe einem MediaPlayer einen Link zu einem Video aus dem Netz.
Dieses spielt er auch ohne Probleme ab. Damit der Downloadfortschritt des Videos angezeigt wird, habe ich eine eigene Progressbar gebastelt und will diese anhand von MediaPlayer.DownloadProgress "füllen". Ich habe es schon mit mehrere Videos ausprobiert, aber DownloadProgress ist immer entweder 0 oder 1. Bei msdn steht:
The percentage of download progress for content located at a remote server represented by a value between 0 and 1.
Der Wert liegt bei mir aber nicht zwischen 0 oder 1, sondern nur auf 0 oder 1, so als ob das Video innerhalb von einer halben Sekunde vollständig geladen wäre (geht natürlich nicht: 1920p x 50min)
Ist das ein Bug von .NET Framework 4.5 oder mach ich was falsch?
Das is nen Double Wert. Wenn Du hier schreibst 1 oder 0 suggeriert das, als ob Du mit Int arbeitest.
Also entweder stimmt nun Dein Datentyp nicht oder Du solltest 0.0 oder 1.0 schreiben.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Stimmt, auf der msdn-Seite ist aber auch von 0 oder 1 die Rede. Aber ja ich arbeite mit Double, das ist es nicht.
Wenn ich jetzt mal meine Glaskugel kontaktiere.. würde ich sagen das das ein Fall für [FAQ] Warum blockiert mein GUI? ist 😉
Es geht nicht um die Progressbar oder sonstiges GUI-relevantes. Es geht darum, dass DownloadProgress nur entweder 0.0 oder 1.0 entgegen der Beschreibung im msdn ist. Ich poste hier auch keinen Code, da ich nicht denke, dass das ganze Codeabhängig ist, da ja der Wert aus dem .NET Framework nicht zu stimmen scheint.
Wenn Du die Antwort schon weist, warum fragst Du dann?
Ich weiß die Antwort auf die Frage, ob das ein Fehler des .NET Frameworks oder mein Fehler ist eben nicht. Deswegen schreibe ich ja nicht zu stimmen scheint. Vielleicht mache ich ja auch irgendwas mit dem Wert falsch.
Hallo UZI,
ich will nicht ausschliessen das es ein Framework Fehler ist, da man zu diesem Fehler allerdings nur mycsharp.de Ergebnisse findet halte ich es nicht für sehr wahrscheinlich.
Am besten nochmal im Minimalprojekt nachstellen ggf. direkt so, dass wir es damit auch nachstellen können.
André
Okay, hier hab ich mal ein Minimalprojekt erstellt:
MediaPlayer player;
DispatcherTimer timer;
public MainWindow()
{
InitializeComponent();
player = new MediaPlayer();
timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0, 0, 0, 0, 250);
timer.Tick += delegate { label1.Content = player.DownloadProgress.ToString(); label1.UpdateLayout(); };
}
private void Window_Loaded_1(object sender, RoutedEventArgs e)
{
Start startform = new Start();
startform.ShowDialog();
if (startform.DialogResult.HasValue && startform.DialogResult.Value)
{
player.MediaOpened += delegate { player.Play(); timer.Start(); };
player.Open(new Uri(startform.txtbox1.Text));
VideoDrawing drawing = new VideoDrawing();
drawing.Rect = new Rect(new Size(1280, 720));
drawing.Player = player;
DrawingBrush brush = new DrawingBrush(drawing);
grid1.Background = brush;
}
else
Close();
}
Startet eine eingegeben URL, und zeigt den DownloadProgress-Wert alle 4tel-Sekunde in einem Label an. Auch hier tritt der Fehler auf. Ich lade das Programm mal mit hoch, dann kann mal jemand anderes es ausprobieren (Bspw. mit diesem Video )
Danke für Rückmeldungen!
Hallo UZI,
sorry aber, ich hatte an ein Kompilierbares Projekt gedacht.
André
Hallo UZI,
das verhalten ist bei mir das Gleiche.
Informationen finde ich jedoch auch keine dazu, sehr seltsam.
Vielleicht gibt es den Status 1 an sobald das Video genügend gepuffert ist.
Eventuell mal eins mit höherer Qualität bzw. Bitrate testen.
Ansonsten mal mit einem Disassembler/Reflector dran gehen.
André
Danke, bin erleichtert, dass es nicht an meinem Code zu liegen scheint. Scheinbar wird die MediaPlayer-Klasse nicht sehr oft verwendet. Ich hatte es auch schon mit 2 Stunden in 1080p ausprobiert, selbes Ergebnis, also scheint nicht so recht Sinn zu machen.
Darf ich rechtlich überhaupt DLLs aus dem .NET Framework decompilen/disassemblieren, um zu schauen ob ein Fehler enthalten ist?
Hallo UZI
Darf ich rechtlich überhaupt DLLs aus dem .NET Framework decompilen/disassemblieren, um zu schauen ob ein Fehler enthalten ist?){gray}
Ja, es handelt sich hierbei um eine readonly Reference-Source-Lizenz.
Das heisst, dekompilieren und schauen ist erlaubt. Kopieren nicht. Nur "sinnesgemäss", also was nach dem schauen im Gedächnis verbleibt, nicht 1:1.
Siehe:
Gruss Peter
--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011
Das mit dem Dekompilieren ist gut zu wissen. Den Code der MediaPlayer-Klasse gibts tatsächlich schon im Netz (hier).
Beim Aufruf MediaPlayer.DownloadProgress wird der Wert von _mediaPlayerState.DownloadProgress genommen. Dort widerrum wird die Methode GetDownloadProgress aus der Klasse MILMedia aufgerufen. Wenn man da reinschaut steht dort ein Dll-Import auf die unmanaged Assembly wpfgfx_v0400.dll am Entrypoint "MILMediaGetDownloadProgress". Aber da kann ich wohl nicht reingucken. Aber über die ganzen Eigenschaften und Methoden wird eigentlich immer der Double-Wert beibehalten, also scheint irgendwas in dieser wpfgfx_v0400.dll nicht zu stimmen.
Gibt es eine Möglichkeit dort reinzuschauen?
Hallo UZI,
hast du ein Link zu einem größeren Clip?
Edit: Hat sich erledigt, mit einem 2GB Clip wird der Progress wie erwartet dargestellt.
Progress: 0
Progress: 0
Progress: 0
Progress: 0
Progress: 0
Progress: 0
Progress: 0
Progress: 0
Progress: 0
Progress: 0
Progress: 0
Progress: 0.01
Progress: 0.01
Progress: 0.01
Progress: 0.01
Progress: 0.01
Progress: 0.01
Progress: 0.01
Progress: 0.01
Progress: 0.01
Progress: 0.01
Progress: 0.01
Progress: 0.01
Progress: 0.01
Progress: 0.01
Progress: 0.01
Progress: 0.02
Progress: 0.02
Progress: 0.02
Progress: 0.02
André
Seltsam, ich habe es gerade mit einem 3-Gigabyte-Video probiert, und kein Ergebniss erzielt. Welche .NET-Framework Version hast du? Meine:
<32Bit>
2.0.50727.5472
->C:\Windows\Microsoft.NET\Framework\v2.0.50727
4.0.30319.18052
->C:\Windows\Microsoft.NET\Framework\v4.0.30319
<64Bit>
2.0.50727.5472
->C:\Windows\Microsoft.NET\Framework64\v2.0.50727
4.0.30319.18052
->C:\Windows\Microsoft.NET\Framework64\v4.0.30319
< Installed .NET Frameworks >
.NET FW 2.0 SP 2
.NET FW 3.0 SP 2
.NET FW 3.5 SP 1
.NET FW 4.5 Client
.NET FW 4.5 Full
von NetDetector
Wäre sehr nett, wenn du deine Version schreiben könntest.
Hallo UZI,
<32Bit>
2.0.50727.5472
->C:\Windows\Microsoft.NET\Framework\v2.0.50727
4.0.30319.18052
->C:\Windows\Microsoft.NET\Framework\v4.0.30319
<64Bit>
2.0.50727.5472
->C:\Windows\Microsoft.NET\Framework64\v2.0.50727
4.0.30319.18052
->C:\Windows\Microsoft.NET\Framework64\v4.0.30319
< Installed .NET Frameworks >
.NET FW 2.0 SP 2
.NET FW 3.0 SP 2
.NET FW 3.5 SP 1
.NET FW 4.5 Client
.NET FW 4.5 Full
Kompiliert mit Zielframework .Net Framework 4.0
Edit: Gleiches Ergebnis bei .Net Framework 4.5
André
Danke TheGear, hat mir auf jeden Fall weitergeholfen. Offensichtlich liegt es also nicht an der .NET-Framework-Version. Als ich das ganze nochmals getestet habe bin ich auf ein einziges Video gestoßen, bei dem das Verhalten anders war (Test-Video 3).
Test-Video 1 - 0.0 oder 1.0
Test-Video 2 - 0.0 oder 1.0
Test-Video 3 - Entweder 0.0 oder 0.01 (???)
Nach diesem Ergebnis, hab ich mir überlegt, worin sich die Videos unterscheiden und mir ist aufgefallen, dass wenn man den Link des dritten Videos im Browser öffnet, wird es nicht wie die beiden anderen Videos direkt im Browser angezeigt, sondern im Downloadmanager gedownloadet. Also nochmal nach einem Video, wie Test-Video 3 gesucht:
Test-Video 4 - 0.0 oder 1.0
Einen Programmierfehler kann ich nun im Grunde ausschließen, einen Kompatibilitätsfehler auch, ein Bug im .NET-Framework scheint es ja auch nicht zu sein (Es funktioniert ja bei TheGear). Auch nach dem Durchlesen dieses Threads: [FAQ] Programm läuft in anderer Umgebung nicht (richtig) bleibt die Frage, was kann es noch sein? Mglw. ein Problem bei den Videos?
_
PS:
Es wird folgende Exception geworfen bei player.Open(url):> Fehlermeldung:
Ausnahme:Aufgefangen: "Die Anwendungsidentität ist nicht festgelegt." (System.Deployment.Application.InvalidDeploymentException)
System.Deployment.Application.InvalidDeploymentException wurde aufgefangen: "Die Anwendungsidentität ist nicht festgelegt."
Hat aber wohl nichts mit diesem Problem zu tun, da es bei allen Videos, sogar bei lokal gespeichterten auftritt._
Fehlermeldung:
Application identity is not set.
heisst in den meisten Fällen, dass eine Exception in einer untergeordneten DLL (zB eine OS-Dll) einen Fehlergeworfen hat, diesen jedoch auch behandelt hat.
Der Debugger zieht hier, weil Du "jede Exception fangen" wohl aktiviert hast.
Wenn ich in die MSDN schaue, und downloadProgress
suche, dann bekomme ich die Info, dass dies nicht für jedes Video funktioniert.
Folgende Typen sind unterstützt: asf, wma, wmv, mp3, mpeg, wav
- aber darüber wirst Du sicherlich auch gestolpert sein.
MILMedia selbst, wovon die Prozentzahl lebt, verweist auf MilCore.dll
und dessen Entrypoint MILMediaGetDownloadProgress
und die holt sichs oder gibts (kanns nich genau nachvollziehen) von/an wpfgfx_v0300.dll
bzw. die entsprechende Version (hier 400.dll).
Die Funktion selbst gibt aber einen Int-Wert zurück (laut Deklaration) - wieso hier irgendwo auf Double umgewandelt wird konnte ich nicht verstehen.
Angesichts Deiner Probleme würde ich also mal den .NET Code Debuggen (ob hier vielleicht ein Fehler passiert) oder zur Not eben direkt auf die C++-Seite wechseln und das IWMPMedia Interface via P/Invoke konsumieren.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
.NET-Code hab ich nach dieser Anleitung debuggt: http://msdn.microsoft.com/de-de/library/vstudio/cc667410(v=vs.110).aspx Zeigt aber keine relevanten Fehler an (meiner meinung nach):> Fehlermeldung:
msg Der Wert von "local" oder von Argument "msg" ist in diesem Anweisungszeiger nicht verfügbar und kann daher nicht ermittelt werden. Möglicherweise wurde er bei der Optimierung entfernt. System.Windows.Interop.MSG
hwnd Der Wert von "local" oder von Argument "hwnd" ist in diesem Anweisungszeiger nicht verfügbar und kann daher nicht ermittelt werden. Möglicherweise wurde er bei der Optimierung entfernt. System.IntPtr
minMessage Der Wert von "local" oder von Argument "minMessage" ist in diesem Anweisungszeiger nicht verfügbar und kann daher nicht ermittelt werden. Möglicherweise wurde er bei der Optimierung entfernt. int
maxMessage Der Wert von "local" oder von Argument "maxMessage" ist in diesem Anweisungszeiger nicht verfügbar und kann daher nicht ermittelt werden. Möglicherweise wurde er bei der Optimierung entfernt. int
MILMedia selbst, wovon die Prozentzahl lebt, verweist auf MilCore.dll und dessen Entrypoint MILMediaGetDownloadProgress und die holt sichs oder gibts (kanns nich genau nachvollziehen) von/an wpfgfx_v0300.dll bzw. die entsprechende Version (hier 400.dll).
Das sieht bei mir anders aus:
//MediaPlayer.cs:
public double DownloadProgress
{
get
{
this.ReadPreamble();
return this._mediaPlayerState.DownloadProgress;
}
}
//MediaPlayerState.cs:
internal double DownloadProgress
{
[SecurityCritical, SecurityTreatAsSafe] get
{
this.VerifyAPI();
double pProgress = 0.0;
HRESULT.Check(MILMedia.GetDownloadProgress(this._nativeMedia, ref pProgress));
return pProgress;
}
}
//MILMedia.cs:
[DllImport("wpfgfx_v0400.dll", EntryPoint = "MILMediaGetDownloadProgress")]
internal static int GetDownloadProgress(SafeMediaHandle THIS_PTR, ref double pProgress);
//Diese Funktion gibt zwar einen int zurück, aber der eigentliche DownloadProgress wird ja über ref weitergegeben, also auch double.
Meinst du ich soll den DllImport mal nachmachen? Wäre aber das Problem, dass ich nicht weiß wie ich an das SafeMediaHandle rankommen soll.
//EDIT
Wo hast du das gelesen mit den unterstützten Formaten, hier steht nichts davon: http://msdn.microsoft.com/de-de/library/system.windows.media.mediaplayer.downloadprogress.aspx
Macht aber sowieso keinen Unterschied, da es auch mit .wmv Dateien nicht funktioniert