![]() |
Verwenden von IAMMediaContent
Die einzige Information die ich habe ist diese hier.
Zitat:
![]() Mein bisher kläglicher versuch.
Delphi-Quellcode:
function KVideo_GetYoutubeFilterTitle(var Title: PWideChar): HRESULT; stdcall;
begin result := E_FAIL; if not Assigned(EVMRPlayer) then exit; result := EVMRPlayer.GetYoutubeFilterTitle(Title); end;
Delphi-Quellcode:
1. Ich weis nicht ob das mit dem Splitter so stimmt.
function TEVMRPlayer.GetYoutubeFilterTitle(var Title: PWideChar): HRESULT;
var MediaContent: IAMMediaContent; Source: IBaseFilter; begin Result := E_FAIL; if IsUrl then begin if DYDYoutubeFilter <> nil then begin if IsRegisteredFilter(CLSID_LegacyAmFilterCategory, CLSID_MPEG1Splitter) then Result := CoCreateInstance(CLSID_MPEG1Splitter, nil, CLSCTX_INPROC_SERVER, IID_IBaseFilter, Source); if SUCCEEDED(Result) then begin Source.QueryInterface(IID_IAMMediaContent, MediaContent); Result := MediaContent.get_Title(Title); if not SUCCEEDED(Result) then ReportError('YoutubeFilterTitle fails', Result); end; end; end; end; 2. Fehlt hier noch irgendwas? Ich habe mich im Net dumm gesucht aber mit dem Stichwort IAMMediaContent findet man fast so gut wie nix. Der Titel soll mir den Namen des Video Streams zurückgeben. Beispiel.. ![]() gruss |
AW: Implementation von IAMMediaContent
Ok! Sorry hat sich erledigt.
So geht es!
Delphi-Quellcode:
srcFilter ist in dem Fall
function TEVMRPlayer.GetYoutubeFilterTitle(var Title: PWideChar): HRESULT;
var MediaContent: IAMMediaContent; begin Result := E_FAIL; if not Assigned(srcFilter) then exit; if IsUrl then begin if DYDYoutubeFilter <> nil then begin srcFilter.QueryInterface(IID_IAMMediaContent, MediaContent); Result := MediaContent.get_Title(Title); if not SUCCEEDED(Result) then ReportError('YoutubeFilterTitle fails', Result); end; end; end;
Delphi-Quellcode:
hr := GraphBuilder.AddSourceFilter(PWideChar(MediaFile), 'SRC01', srcFilter);
Was für ein Aufwand bis das mal alles steht. Pic von Vimeo, YouTube Jetzt fehlt noch die Video Auflösung und die Laufzeit. gruss |
AW: Implementation von IAMMediaContent
Du willst also
Delphi-Quellcode:
gar nicht implementieren sondern verwenden? Dann ist der Titel Implementation von IAMMediaContent etwas irreführend.
IAMMediaContent
Wenn du nicht aufpasst, dann hast du hier einen schönen Memleak, denn du musst den zurückgegebenen Text von
Delphi-Quellcode:
auch wieder aus dem Speicher räumen (
IAMMediaContent::get_Title
![]() Am einfachsten ist das, wenn du dieses direkt in der Methode
Delphi-Quellcode:
erledigst. Dort kopierst du den Text von unmanaged zu managed (von dem Pointer in einen string) und gibst den unmanaged Speicher direkt frei.
TEVMRPlayer.GetYoutubeFilterTitle
|
AW: Implementation von IAMMediaContent
Zitat:
Ich denke du meinst das so.
Delphi-Quellcode:
function TEVMRPlayer.GetYoutubeFilterTitle(var Title: PWideChar): HRESULT;
var MediaContent: IAMMediaContent; pTitle: PWideChar; begin Result := E_FAIL; if not Assigned(srcFilter) then exit; if IsUrl then begin if DYDYoutubeFilter <> nil then begin srcFilter.QueryInterface(IID_IAMMediaContent, MediaContent); Result := MediaContent.get_Title(pTitle); Title := pTitle; pTitle := nil; if not SUCCEEDED(Result) then ReportError('YoutubeFilterTitle fails', Result); end; end; end; Zitat:
Zitat:
gruss |
AW: Verwenden von IAMMediaContent
So sollte das tun
Delphi-Quellcode:
function TEVMRPlayer.GetYoutubeFilterTitle(out Title: string): HRESULT;
var MediaContent: IAMMediaContent; pbstrTitle: PWideChar; begin Result := E_FAIL; if not Assigned(srcFilter) then exit; if IsUrl then begin if DYDYoutubeFilter <> nil then begin srcFilter.QueryInterface(IID_IAMMediaContent, MediaContent); Result := MediaContent.get_Title(pbstrTitle); if not SUCCEEDED(Result) then ReportError('YoutubeFilterTitle fails', Result) else begin Title := pbstrTitle; FreeMem(pbstrTitle); end; end; end; end; Zitat:
Delphi-Quellcode:
ist? Etwa ein Pointer und deswegen fängt der Typ auch mit einem P an?
PWideChar
|
AW: Verwenden von IAMMediaContent
Ahh dann war ich fast richtig. Siehe mein Edit.
Danke dir. Werde das auch bei Description berücksichtigen (ist noch nicht implementiert) Zitat:
Deshalb habe ich gesagt der soll PWideChar bleiben. (Pointer of WideChar) Ich habe es so verstanden.
Delphi-Quellcode:
gruss
var
x: string //.. x := string(Title); |
AW: Verwenden von IAMMediaContent
Zitat:
Der FreeMem auf dem Pointer ist das Entscheidende |
AW: Verwenden von IAMMediaContent
Zitat:
Auf jeden fall danke für den Hinweis. gruss |
AW: Verwenden von IAMMediaContent
Wenn du weiterhin Title als PWideChar übergeben willst, dann hast du jetzt zwei Möglichkeiten:
1. Du hast einen MemLeak, weil alle Stllen die diese Methode verwenden den Speicherbereich nicht freigeben. 2. Es knallt, wenn du den Speicher in der Methode schon freigibst. Die beste Variante ist die von mir gezeigte
Delphi-Quellcode:
, denn dort hast du weder ein MemLeak noch einen SPeicherzugriffsfehler, egal was du anstellst. Ist allerdings auch nur eine Empfehlung wie ich das machen würde, weil es das Leben einfacher macht.
function TEVMRPlayer.GetYoutubeFilterTitle(out Title: string): HRESULT;
|
AW: Verwenden von IAMMediaContent
Nun Praxis und versuch sind zwei Dinge.
Die Anwendung stürzt nun ab bei FreeMem. gruss |
AW: Verwenden von IAMMediaContent
Zitat:
|
AW: Verwenden von IAMMediaContent
Zitat:
Ich mache es genauso wie von dir gezeigt und verwende genau deine Funktion. Deine Antwort.. Zitat:
Schritt für Schritt also siehe..
Delphi-Quellcode:
var
FileName: string; //.. if InStr(lowercase(FileName), '//') = 1 then begin hr := KVideo_GetYoutubeFilterTitle(FileName); if SUCCEEDED( hr)then SKAERO_SetCTLText(gP.MainHandle, FileName); end else SKAERO_SetCTLText(gP.MainHandle, FileName);
Delphi-Quellcode:
function KVideo_GetYoutubeFilterTitle(out Title: string): HRESULT; stdcall;
begin result := E_FAIL; if not Assigned(EVMRPlayer) then exit; result := EVMRPlayer.GetYoutubeFilterTitle(Title); end;
Delphi-Quellcode:
Also was denn nun?
function TEVMRPlayer.GetYoutubeFilterTitle(out Title: string): HRESULT;
var MediaContent: IAMMediaContent; pbstrTitle: PWideChar; begin Result := E_FAIL; if not Assigned(srcFilter) then exit; if IsUrl then begin if DYDYoutubeFilter <> nil then begin srcFilter.QueryInterface(IID_IAMMediaContent, MediaContent); Result := MediaContent.get_Title(pbstrTitle); if not SUCCEEDED(Result) then ReportError('YoutubeFilterTitle fails', Result) else begin Title := pbstrTitle; FreeMem(pbstrTitle); // Crash! end; end; end; end; Deine Methode oder nicht! Dein FreeMem lässt die Anwendung auf jeden fall abstürzen genau das gleiche wenn ich pbstrTitle auf Nil setze. Mit der Freigabe wird das wohl nix oder? gruss |
AW: Verwenden von IAMMediaContent
Ja, ich denke ich habe das Problem lokalisiert und kann dir morgen eine Lösung geben.
Ich vermute, dass die von dir verwendete Interface Deklaration von IAMMediaContent falsch ist. Aber dazu morgen mehr. |
AW: Verwenden von IAMMediaContent
Zitat:
Aber Ok.. Danke. gruss |
AW: Verwenden von IAMMediaContent
So, jetzt nochmals nachgelesen und wenn man ganz exakt der Dokumentation folgt, dann müsste es so sein (nicht getestet)
Delphi-Quellcode:
uses
... Winapi.ActiveX; function TEVMRPlayer.GetYoutubeFilterTitle(out Title: string): HRESULT; var MediaContent: IAMMediaContent; pbstrTitle: {Winapi.ActiveX.}TBSTR; begin Result := E_FAIL; if not Assigned(srcFilter) then exit; if IsUrl then begin if DYDYoutubeFilter <> nil then begin srcFilter.QueryInterface(IID_IAMMediaContent, MediaContent); Result := MediaContent.get_Title(pbstrTitle); if not SUCCEEDED(Result) then ReportError('YoutubeFilterTitle fails', Result) else begin Title := OleStrToString(pbstrTitle); {Winapi.ActiveX.}SysFreeString(pbstrTitle); end; end; end; end; |
AW: Verwenden von IAMMediaContent
Hui das Ding kannte ich auch noch nicht, SysFreeString, müßte das nicht noch in dem " if DYDYoutubeFilter <> nil then" block aufgerufen werden anstelle nur im "if not SUCCEEDED(Result) then" block?
|
AW: Verwenden von IAMMediaContent
Zitat:
Ein Aufruf mit
Delphi-Quellcode:
ist aber unkritisch von daher kann man es pauschal immer aufrufen, muss man aber nicht.
nil
Denkbar ist also auch
Delphi-Quellcode:
PS
uses
... Winapi.ActiveX; function TEVMRPlayer.GetYoutubeFilterTitle(out Title: string): HRESULT; var MediaContent: IAMMediaContent; pbstrTitle: {Winapi.ActiveX.}TBSTR; begin Result := E_FAIL; if not Assigned(srcFilter) then exit; if IsUrl then begin if DYDYoutubeFilter <> nil then begin srcFilter.QueryInterface(IID_IAMMediaContent, MediaContent); pbstrTitle := nil; try Result := MediaContent.get_Title(pbstrTitle); if not SUCCEEDED(Result) then ReportError('YoutubeFilterTitle fails', Result) else Title := OleStrToString(pbstrTitle); finally {Winapi.ActiveX.}SysFreeString(pbstrTitle); end; end; end; end; Wer meint, er kann darauf nicht reinfallen, weil er mit
Delphi-Quellcode:
arbeitet, dem sei gesagt, dass hier gar nichts gemeldet wird.
ReportMemoryLeaksOnShutdown := true
Kleiner Test (bei der Ausführung einen Blick auf den Taskmanager und den verwendeten Arbeitsspeicher haben)
Delphi-Quellcode:
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm1 = class( TForm ) Button1: TButton; FreeString_CheckBox: TCheckBox; procedure Button1_Click( Sender: TObject ); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation uses Winapi.ActiveX, System.StrUtils; {$R *.dfm} function GetString( AFreeString: boolean ): string; var pbstrTemp: TBSTR; begin pbstrTemp := StringToOleStr( DupeString( 'TestTest', 4096 ) ); try Result := OleStrToString( pbstrTemp ); finally if AFreeString then SysFreeString( pbstrTemp ); end; end; procedure TForm1.Button1_Click( Sender: TObject ); var r: string; I: Integer; begin ReportMemoryLeaksOnShutdown := True; for I := 1 to 4096 do begin r := GetString( FreeString_CheckBox.Checked ); end; end; |
AW: Verwenden von IAMMediaContent
Schön gezaubert und gut erklärt, Dankeschön dafür!:thumb:
edit Miniexperiment:
Delphi-Quellcode:
so scheint es sich selbst zu bereinigen.
pbstrTemp := PWideChar( DupeString( 'TestTest', 4096 ) );
|
AW: Verwenden von IAMMediaContent
Wüsste jetzt nicht was TBSTR bringen soll.
PWideChar bleibt PWideChar egal wie am ende die Benennung ist. Ist letztendlich auch nur ein PWideChar. ( POleStr = PWideChar; ) Die anderer Sache du schiebst hier einige dinge hin und her. Was soll das mit out, var warum änderst du meine Ausgangsvariable von var nach out? Schließlich verwendet die API var und nicht out.
Delphi-Quellcode:
var nicht out!
function get_Title(var pbstrTitle: TBSTR): HResult; stdcall;
gruss |
AW: Verwenden von IAMMediaContent
Emil, wenn Du keine Hilfe willst, warum fragst Du dann? :gruebel:
|
AW: Verwenden von IAMMediaContent
Zitat:
Muss ich alles ab nicken ohne selbst zu Denken? Definitiv ist TBSTR nicht nötig.. ein unnötiges hin und her casten macht irgendwie keinen sinn. Zudem wenn die API als Ausgangsparameter var verwendet dann ist es für mich fraglich diesen nach out umzulegen. Das hat nichts mit Hilfe wollen mehr oder weniger zu tun. Es wäre also sinnvoller gewesen wenn du mir daraufhin eine Antwort gegeben hättest anstelle mich hier zu maßregeln. Also! Frage 1 warum castet man hier von var nach out Frage 2 welchen sinn macht die Definition TBSTR wenn es am ende doch PWideChar ist.. Es bleibt am ende gleich. (Nur eine frage der Namensgebung aber gleiche Funktionalität) Vielleicht kannst du es beantworten.
Delphi-Quellcode:
So geht es jetzt.
function TEVMRPlayer.GetYoutubeFilterTitle(var Title: string): HRESULT;
var MediaContent: IAMMediaContent; pbstrTitle: PWideChar; begin Result := E_FAIL; if not Assigned(srcFilter) then exit; if IsUrl then begin if Assigned(DYDYoutubeFilter) then begin srcFilter.QueryInterface(IID_IAMMediaContent, MediaContent); Result := MediaContent.get_Title(pbstrTitle); if not SUCCEEDED(Result) then ReportError('YoutubeFilterTitle fails', Result) else begin Title := pbstrTitle; SysFreeString(pbstrTitle); end; end; end; end; War IAMMediaContent doch nicht falsch ;) Nochmals Danke für den Hinweis auf das Speicherleck. gruss |
AW: Verwenden von IAMMediaContent
Zitat:
Gratuliere zum Erfolg! |
AW: Verwenden von IAMMediaContent
Zitat:
gruss |
AW: Verwenden von IAMMediaContent
Ich habe nicht behauptet das das Interface IAMMediaContent falsch ist, ich hatte es vermutet und diese Vermutung traf nicht zu. Dieses ist auch noch nachzulesen.
Die Definition des Interfaces verwendet TBSTR (Winapi.DirectShow9) und genau diesen Typen verwende ich dann auch. Mir egal ob das in der Konsequenz ein PWideChar ist. Und ob man TBSTR oder PWideChar verwendet ist pupsegal, und gecastet wird da gar nichts. Du verwendest auch ein HRESULT obwohl das eigentlich ein Cardinal ist. Warum? Eben, es ist das Gleiche. Wenn man den Code aber mit der API Beschreibung vergleicht trifft man auf diese Namensgebung und muss nicht immer hin- und herdenken. Darum arbeitet man mit einem Type-Alias. Ich nehme ein
Delphi-Quellcode:
weil jeder Wert der in diese Methode hineinkommt niemals verwendet wird. Es macht keinen Unterschied hier einfach ein
out
Delphi-Quellcode:
zu nehmen. Es geht nur darum dem Verwender der Methode mitzuteilen, das der Wert den er hier hineingibt nicht verwendet wird. Es ist also ein reiner
var
Delphi-Quellcode:
Parameter.
out
Es gibt andere Methoden da ist es ein in/out Parameter, da verwende ich dann
Delphi-Quellcode:
und bei einem reinen in Parameter verwende ich
var
Delphi-Quellcode:
.
const
Es gibt halt einen Unterschied zwischen kompiliert, funktioniert und formal korrekt. Ich bin halt pingelig und jeder darf seinen Anspruch weiter rauf oder runterschrauben wie es ihm beliebt. Von jemandem aus Unwissenheit über die formale Korrektheit anfurzen zu lassen möchte ich mir aber doch verbitten. Take it or leave it or frage freundlich nach |
AW: Verwenden von IAMMediaContent
Zitat:
Ändert aber nichts an meiner Auslegung egal wie du das sehen magst. Ich habe auch meine Eigenheiten und wenn du es als unwissend hinstellst das ich PWideChar verwende anstelle deines TBSTR damit kann ich leben aber es ändert nichts am Endresultat. Ob ich nun ein Ei koche, brate oder Roh esse es ist am ende ein Ei in welcher form auch immer. Das ist meine formale Korrektheit. Schwer empfindlich oder? PS: Das einige Leute immer direkt beleidigt spielen nur weil ich nicht alles übernehme so wie Sie es für richtig halten. gruss |
AW: Verwenden von IAMMediaContent
Zitat:
Zitat:
|
AW: Verwenden von IAMMediaContent
Zitat:
Vielleicht gefällt dir diese Aussage besser. Könnte aber sein das es auch wieder Unwissenheit ist. In meinen Kreisen nennt man das Pfennigfuchser. (Alles auf die Goldwaage legen). Wie man etwas benennt bleibt doch gleich verwende du deine Art und weise so etwas zu handhaben und ich die meine. Ich bin ja Dankbar für deine Hilfe das schließt aber nicht mit ein das ich alles, 1 zu 1 deiner Vorschläge übernehmen muss. Zitat:
Zitat:
Ok! Thema für mich erledigt. Danke. gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:30 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz