Jump to content

DVBViewer mittels com+ ansprechen/steuern


dave090679

Recommended Posts

Hallo Leute,

Ich möchte für das Bildschirmleseprogramm NVDA (http://www.nvda-project.org) eine Erweiterung erstellen, mit deren Hilfe es möglich ist, das OSD des Dvbviewers zu bedienen Bzw. dessen Inhalte vorgelesen zu bekommen. Hierzu möchte ich das com-objekt des Dvbviewers verwenden und auf dessen Ereignisse reagieren. so soll z.b. beim Umschalten der Name des neuen Senders und der Titel der laufenden Sendung angesagt werden. Außerdem möchte ich das Menü zugänglich machen: beim Navigieren mit der Fernbedienung soll der hervorgehobene Eintrag angesagt werden.

NVDA-Erweiterungen werden in Python geschrieben (wir verwenden momentan noch Python 2.7, weil noch nicht alle zum Compilieren von NVDA nötigen Komponenten für Python 3 verfügbar sind [wie etwa py2exe]), aber das nur nebenbei:-).

Wenn ich nun einen vorhandenen (laufenden) DVBViewer "anzapfen" möchte, bekomme ich folgende Fehlermeldung angezeigt und das objekt wird nicht erstellt:
>>> DVBViewer = comtypes.client.GetActiveObject("DVBViewerServer.DVBViewer")
# Generating comtypes.gen._017FD4A8_5E00_4DF8_A388_434B8E592CC4_0_1_1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\comtypes\client\__init__.py", line 183, in
GetActiveObject
return _manage(obj, clsid, interface=interface)
File "C:\Python27\lib\site-packages\comtypes\client\__init__.py", line 188, in
_manage
obj = GetBestInterface(obj)
File "C:\Python27\lib\site-packages\comtypes\client\__init__.py", line 110, in
GetBestInterface
mod = GetModule(tlib)
File "C:\Python27\lib\site-packages\comtypes\client\_generate.py", line 112, i
n GetModule
mod = _CreateWrapper(tlib, pathname)
File "C:\Python27\lib\site-packages\comtypes\client\_generate.py", line 188, i
n _CreateWrapper
mod = _my_import(fullname)
File "C:\Python27\lib\site-packages\comtypes\client\_generate.py", line 26, in
_my_import
return __import__(fullname, globals(), locals(), ['DUMMY'])
File "C:\Python27\lib\site-packages\comtypes\gen\_017FD4A8_5E00_4DF8_A388_434B
8E592CC4_0_1_1.py", line 2763
None = 0
SyntaxError: cannot assign to None

Was mache ich falsch?


Eine ähnliche Fehlermeldung bekomme ich auch angezeigt, wenn ich versuche, mit CreatrObject eine neue DVBViewer-Instanz zu öffnen:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\comtypes\client\__init__.py", line 242, in
CreateObject
return _manage(obj, clsid, interface=interface)
File "C:\Python27\lib\site-packages\comtypes\client\__init__.py", line 188, in
_manage
obj = GetBestInterface(obj)
File "C:\Python27\lib\site-packages\comtypes\client\__init__.py", line 110, in
GetBestInterface
mod = GetModule(tlib)
File "C:\Python27\lib\site-packages\comtypes\client\_generate.py", line 112, i
n GetModule
mod = _CreateWrapper(tlib, pathname)
File "C:\Python27\lib\site-packages\comtypes\client\_generate.py", line 188, i
n _CreateWrapper
mod = _my_import(fullname)
File "C:\Python27\lib\site-packages\comtypes\client\_generate.py", line 26, in
_my_import
return __import__(fullname, globals(), locals(), ['DUMMY'])
File "C:\Python27\lib\site-packages\comtypes\gen\_017FD4A8_5E00_4DF8_A388_434B
8E592CC4_0_1_1.py", line 1942
None = 0
SyntaxError: cannot assign to None


der DVBViewer wird zwar gestartet, das oben genannte Objekt wird aber nicht erstellt.

Weitere Infos zu Erweiterungen für NVDA sind im Entwicklerhandbuch von NVDA entweder in englisch unter http://community.nvda-project.org/documentation/developerGuide.html oder in deutsch unter https://dl.dropboxusercontent.com/u/67471/developerGuide.html

Danke im Voraus


Dave

Link to comment

Hi,

 

im Moment wollte ich nur mal in der Python-Konsole testen, ob ich überhaupt mit dem DVBViewer-com-Objekt "reden" kann:-). u.a. wollte ich das Objekt mal ein wenig aushorchen:

 

DVBViewer = comtypes.client.GetActiveObject("dvbviewerserver.DVBViewer")

help(DVBViewer)

dir(DVBViewer)

print DVBViewer.__dict__

 

naja, und wenn das funktioniert hätte, dann hätte ich damit beginnen können, ein Anwendungsmodul für NVDA zu bauen. Ich hab mal mit Powershell in das Com-Objekt reingeschnuppert und die Ereignisse, die der mir da angezeigt hat, sahen vielversprechend aus.

 

mfg

 

Dave

Link to comment

hi ihr,

 

Ich bin mittlerweile ein wenig weitergekommen und kann zumindest schon einmal mit dem DVBViewer reden, ich muss aber genau wissen, was ich von ihm will:-).

 

>>> DVBViewer = comtypes.client.GetActiveObject("dvbviewerserver.DVBViewer", dynamic=True)

das klappt, wenn auch nur als dynamische Einbindung; das com-Objekt wird tatsächlich angelegt.

>>> print DVBViewer.currentchannelnr
242

das klappt; und auch so was wie

>>> print DVBViewer.currentchannel.name
VOX
... klappt auch; aber ich muss wie gesagt genau wissen, was ich von ihm will; ihn fragen, was er so alles kann, funktioniert leider nicht:-(.

>>> help(DVBViewer)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "pythonConsole.pyc", line 30, in __call__
File "pydoc.pyc", line 1748, in __call__
File "pydoc.pyc", line 1795, in help
File "pydoc.pyc", line 1532, in doc
File "pydoc.pyc", line 1506, in render_doc
File "pydoc.pyc", line 1501, in resolve
File "comtypesMonkeyPatches.pyc", line 34, in new__getattr__
File "comtypes\client\dynamic.pyc", line 93, in __getattr__
File "comtypes\automation.pyc", line 643, in GetIDsOfNames
COMError: (-2147352570, 'Unbekannter Name.', (None, None, None, 0, None))
das macht aber nichts, dafür hab ich mir das sdk aus dem Mitgliederbereich gezogen

 

leider kann ich auch keine Ereignisse vom DVBViewer entgegennehmen:-(.

>>> comtypes.client.ShowEvents(DVBViewer)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "comtypes\client\_events.pyc", line 218, in ShowEvents
File "comtypes\client\_events.pyc", line 193, in GetEvents
File "comtypes\client\_events.pyc", line 73, in FindOutgoingInterface
TypeError: cannot determine source interface

 

Aufgrund der obigen Fehlermeldung habe ich ach so meine Zweifel, dass ich mit getevents eine eigene Ereignisbehandlungsroutine dranhängen kann.

 

 

mfg

 

Dave

Link to comment

hi ihr,

 

Ich bin mittlerweile ein wenig weitergekommen und kann zumindest schon einmal mit dem DVBViewer reden, ich muss aber genau wissen, was ich von ihm will:-).

 

>>> DVBViewer = comtypes.client.GetActiveObject("dvbviewerserver.DVBViewer", dynamic=True)

 

das klappt, wenn auch nur als dynamische Einbindung; das com-Objekt wird tatsächlich angelegt.

>>> print DVBViewer.currentchannelnr

242

das klappt; und auch so was wie

>>> print DVBViewer.currentchannel.name

VOX

... klappt auch; aber ich muss wie gesagt genau wissen, was ich von ihm will; ihn fragen, was er so alles kann, funktioniert leider nicht:-(.

Aufgrund der obigen Fehlermeldung habe ich ach so meine Zweifel, dass ich mit getevents eine eigene Ereignisbehandlungsroutine dranhängen kann.

 

 

mfg

 

Dave

 

Was er kann entnimmst du am besten der Datei DVBViewer COM Interface. Findest du beim SDK im membersbereich.

 

Das mit den events wird vermutlich wirklich nicht klappen. Dazu muesstest du einen plugin schreiben welcher events an deinen COM port schickt. Einige Sachen koennen auch ueber commands.ini oder die DVBViewer Skripte gemacht werden.

 

Eine ganze Menge von Daten kann man mit dem DVB Spy (auch members Bereich) auslesen. Diese Variablen koennen ueber COM ausgelesen werden. Dort sind Sendernahmen, Titel der aktuellen Sendung usw. drin.

myTVtitle = DVBViewer.DataManager.Value["#TV.title.now"]

myTVtitle wuerde dann z.B. Tagesschau enthalten.

 

Wichtig sind auch die Fensternummern.. erm window ID's. Das laufende TV Bild hat die ID 0. Wenn du bei window ID 0 den event 5000 abschickst, dann geht das Menue auf. Wenn du in window ID 0 den event fuer den OK Knopf schickst geht das MiniEPG auf. Die window IDs kannst du alle im DVB Spy auslesen. Fensternahmen werden dort auch angezeigt und koennen mit DataManger.value ausgelesen werden.

 

 

Auch mal folgendes lesen:

http://de.DVBViewer.tv/wiki/Actions.ini

http://de.DVBViewer.tv/wiki/Command.vbs

http://de.DVBViewer.tv/wiki/DVBViewer_VBScripte

http://de.DVBViewer.tv/wiki/Commands.ini

 

 

Beispiel:

 

Du kannst in channelchange.vbs erkennen das umgeschalten wurde. Nun kannst du auf die eine oder andere Art dafuer sorgen, dass der Titel der Sendung vorgelesen wird.

 

 

Edit: Ah, ich sehe nuts hat einen Eventhandler gebaut. Damit kann man sicher noch viel mehr anstellen.

Edited by mague
Link to comment

Edit: Ah, ich sehe nuts hat einen Eventhandler gebaut. Damit kann man sicher noch viel mehr anstellen.

 

Ne das normale EG-Plugin ist nicht von mir und mein kleines EG Plugin enthält keinen Eventhandler.

Hier kann man sich das anschauen: http://www.DVBViewer.tv/forum/topic/49985-eventghost-DVBViewer-plugin-new-version/

Das Plugin ist zwar recht umfangreich, aber dafür in Python und das sollte dann schon verständlich sein.

 

Es lassen sich problemlos Ereignisse per Skript empfangen.

Link to comment

Hallo Leute,
Vielen vielen Dank für eure Unterstützung!! Leider kann ich vbs (noch) nicht so gut, als dass ich euren Vorschlag mit den vbs-Scriptings umsetzen könnte. Aus diesem Grund werde ich mich auf Python beschränken müssen.

Mittlerweile bin ich ein gutes Stück weitergekommen und habe ihm zwar die Fehlermeldungen abgewöhnen können, kann aber nach wie vor keine Ereignisse vom DVBViewer entgegennehmen Bzw. darauf reagieren. Ich hänge euch mal den Code nebst Kommentaren ran. Für mich sieht es jedenfalls so aus, als ob in meiner "Ereignissenke" einfach nichts ankommt, obwohl im dvbspy zumindest einige Ereignisse ankommen (die osd-ereignisse sind nämlich nicht dabei).

Für eure hilfe danke ich im Voraus.

Mein Anwendungsmodul könnt ihr euch hier runterladen: https://dl.dropboxusercontent.com/u/67471/DVBViewer.py
das von Python (respektive von comtypes.gen) erzeugte Modul gibt's hier: https://dl.dropboxusercontent.com/u/67471/dvbviewerhelper.py
Wenn ihr den Code testen wollt, reicht es NVDA die Dateien unterzuschieben und Anschließend entweder nvda neu zu starten oder mit nvda+strg+f3 die Plug-ins neu zu laden.
Wenn ihr eine installierte Version von nVDA benutzt, müsst ihr beide Dateien in %userprofile%\Anwendungsdaten\nvda\appmodules kopieren (Bzw. %userprofile%\appdata\roaming\appmodules
wenn ihr eine portable Version von NVDA habt, müssen die Dateien in den Unterordner userconfig\appmodules kopiert werden.

mfg

Dave

Link to comment

Hallo Leute,

zu meiner vorigen Nachricht möchte ich noch nachtragen, dass ihr das Protokoll von nvda entweder über den Menüpunkt extras --> Protokollbetrachter erreicht, oder ihr öffnet die Datei %temp%\nvda.log. Dort sollten Einträge erscheinen, wenn ihr bei ausgeschalteter Behindertenunterstützung im osd navigiert (sofern Ereignisse durchkommen).

den kompletten Quellcode für die Erweiterung könnt ihr übrigens auch hier per git auschecken: https://bitbucket.org/dave090679/DVBViewer

mfg

Dave

Link to comment

Hallo Leute,

 

Als Alternativlösung habe ich mir soeben activepython an Land gezogen und werde im Laufe der nächsten Woche mal versuchen, den Spieß umzudrehen d.h. NVDA vom DVBViewer aus über dessen Scripting-Schnittstelle anzusprechen. Mein Plan ist, mit Dateien wie onselecteditem.py, onosdwindow.py usw. im DVBViewer-Scripting-Verzeichnis auf dessen Ereignisse mit dem Aufruf des nvda-controller-clients zu reagieren. Das ist eine kleine dll, mit der man den nvda gewissermaßen fernsteuern kann. Der nvda-controller-client enthält auch eine Funktion, mit der man ui.message-ähnliche Meldungen per Sprache und/oder per Braille ausgeben kann, also genau das, was ich will.

 

mfg

 

Dave

Link to comment

Hallo Leute,

Vielen Dank für eure Geduld und Unterstützung!
Ich habe mein Problem (hoffentlich) nachhaltig gelöst bekommen. Die Ursache war ein falscher Geltungsbereich der Verbindung zwischen DVBViewer und Nvda. Die Verbindung ist in dem Moment in die Brüche gegangen, als die __init__-Methode meines Anwendungsmoduls beendet wurde. Anders ausgedrückt hat die Verindung - wenn überhaupt - nur ganz kurz beim Start von DVBViewer gelebt. Die Ereignisse kamen also deshalb nicht durch, weil die Verbindung zu dem Zeitpunkt, da ich den DVBViewer nach dem Start bedienen will, schon gar nicht mehr exitiert hat.

Ich habe einfach
connection = comtypes.client.getevents(...) geändert in
self.connection = comtypes.client.getevents(...)

Die Verbindung zwischen NVDA und DVBViewer bleibt jetzt die ganze Zeit am leben, wenn ich den DVBViewer bediene und die Ereignisse kommen alle wunderbar durch.
Nun funktioniert alles wie erwartet.

Nochmals vielen Dank für eure Unterstützung.

mfg

Dave

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...