|
|
Is there a way to play VOB files copied from a DVD to the HD using the WMP ActiveX control WITHOUT changing the file extensions to .mpg?
|
|
From: "ejm3"
[Quoted Text] > Is there a way to play VOB files copied from a DVD to the > HD using the WMP ActiveX control WITHOUT changing the > file extensions to .mpg?
WMP doesn't care about file extensions.
-- // Alessandro Angeli // MVP :: DirectShow / MediaFoundation // mvpnews at riseoftheants dot com // http://www.riseoftheants.com/mmx/faq.htm
|
|
If one copies a VOB file from a physical mastered DVD to the local hard drive it will not play using WMP. This is supported behaviour and it doesn't seem to be limited to protected disks:
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q316992 http://support.microsoft.com/kb/313327/en-us
However, as noted many times in this very forum, if one changes the file extension of this copied VOB file from .vob to .mpg it WILL play correctly using WMP.
Therefore, I don't understand your response at all.
"Alessandro Angeli" wrote:
[Quoted Text] > From: "ejm3" > > > Is there a way to play VOB files copied from a DVD to the > > HD using the WMP ActiveX control WITHOUT changing the > > file extensions to .mpg? > > WMP doesn't care about file extensions. > > -- > // Alessandro Angeli > // MVP :: DirectShow / MediaFoundation > // mvpnews at riseoftheants dot com > // http://www.riseoftheants.com/mmx/faq.htm > > >
|
|
From: "ejm3"
[Quoted Text] One of the articles simply states that Windows itself, not WMP, will not let you read files from protected DVDs. If you have an unprotected disk, you can instead copy the files.
The other article says that WMP does not support VOB files at all, not even by renaming them to MPG. That's because VOB files are MPEG-2 PS files (which WMP supports) but they usually contain MPEG-2 video and AC-3, LPCM or DTS audio, which WMP does not support. If a VOB were to contain MPEG-1 video and MPEG-1 audio (which is DVD-compliant but almost never used), then it would play, regardless of the extension.
If on your system renaming a VOB to MPG makes it play in WMP, that means you have installed third-party decoders for the audio and video formats used in the VOB. In that case, the VOB will play regardless of the extension, because WMP does not rely on the extension but on the file signature (the beginning of the file) to discover the file type.
-- // Alessandro Angeli // MVP :: DirectShow / MediaFoundation // mvpnews at riseoftheants dot com // http://www.riseoftheants.com/mmx/faq.htm
|
|
Now we're getting somewhere!
Thanks for the thorough explanation. It is in fact very good news that WMP does not rely on the file extension but rather on the file signature (header info) to determine file type. This is in fact what I assumed to be the case. However, in contrast to what you state, my colleague has assured me that there are cases where a .vob file named as such will fail to play but when renamed to .mpg will succeed. So, although third party decoders obviously exist on the system in question, in one case they are not "found" or "used" whereas in the other they are.
At this point it is probably best for me to get an example file to confirm this and upload it for testing.
"Alessandro Angeli" wrote:
[Quoted Text] > From: "ejm3" > > > If one copies a VOB file from a physical mastered DVD to > > the local hard drive it will not play using WMP. This is > > supported behaviour and it doesn't seem to be limited to > > protected disks: > > > > http://support.microsoft.com/default.aspx?scid=kb;en-us;Q316992> > http://support.microsoft.com/kb/313327/en-us> > > > However, as noted many times in this very forum, if one > > changes the file extension of this copied VOB file from > > .vob to .mpg it WILL play correctly using WMP. > > > > Therefore, I don't understand your response at all. > > One of the articles simply states that Windows itself, not > WMP, will not let you read files from protected DVDs. If you > have an unprotected disk, you can instead copy the files. > > The other article says that WMP does not support VOB files > at all, not even by renaming them to MPG. That's because VOB > files are MPEG-2 PS files (which WMP supports) but they > usually contain MPEG-2 video and AC-3, LPCM or DTS audio, > which WMP does not support. If a VOB were to contain MPEG-1 > video and MPEG-1 audio (which is DVD-compliant but almost > never used), then it would play, regardless of the > extension. > > If on your system renaming a VOB to MPG makes it play in > WMP, that means you have installed third-party decoders for > the audio and video formats used in the VOB. In that case, > the VOB will play regardless of the extension, because WMP > does not rely on the extension but on the file signature > (the beginning of the file) to discover the file type. > > -- > // Alessandro Angeli > // MVP :: DirectShow / MediaFoundation > // mvpnews at riseoftheants dot com > // http://www.riseoftheants.com/mmx/faq.htm > > >
|
|
From: "ejm3"
[Quoted Text] > colleague has assured me that there are cases where a > .vob file named as such will fail to play but when > renamed to .mpg will succeed. So, although third party
What error code does he get?
-- // Alessandro Angeli // MVP :: DirectShow / MediaFoundation // mvpnews at riseoftheants dot com // http://www.riseoftheants.com/mmx/faq.htm
|
|
Well, I have personally tested a VOB file and confirmed that with a file extension of .vob it loads in both the standalong WMP and the ActiveX control and appears to play but no video or audio is rendered i.e. black screen and no audio. If the extension is changed to .mpg it appears to play normally. No errror messages are displayed in either case.
You can download test files here: http://www.exponentsoftware.com/en/technical-stuff.php?id=media
- click on the .vob (DVD) format
"Alessandro Angeli" wrote:
[Quoted Text] > From: "ejm3" > > > colleague has assured me that there are cases where a > > .vob file named as such will fail to play but when > > renamed to .mpg will succeed. So, although third party > > What error code does he get? > > > -- > // Alessandro Angeli > // MVP :: DirectShow / MediaFoundation > // mvpnews at riseoftheants dot com > // http://www.riseoftheants.com/mmx/faq.htm > > >
|
|
hi,
[Quoted Text] > Is there a way to play VOB files copied from a DVD to the HD using the WMP > ActiveX control WITHOUT changing the file extensions to .mpg?
Yes, if you have a Codec like FFdShow : *** snip *** CASE ".VOB" $ UPPER(cFile) // Video-DVD nPosi := RAT("\",cFile) IF nPosi > 0 cPath := UPPER(LEFT(cFile,nPosi - 1)) cFile := "wmpdvd://Z/1/1?contentdir="+cPath cFiles[ i ] := cFile ENDIF *** EOF *** but if i remember right "cPATH" must be a "Root" like "Z:\"
greetings by OHR Jimmy
|
|
From: "ejm3"
[Quoted Text] > Well, I have personally tested a VOB file and confirmed > that with a file extension of .vob it loads in both the > standalong WMP and the ActiveX control and appears to > play but no video or audio is rendered i.e. black screen > and no audio. If the extension is changed to .mpg it > appears to play normally. No errror messages are > displayed in either case.
What do you know? They made WMP "smarter" :-) It looks like now WMP forcefully renders .VOB files with the DVD graph builder and this choice seems to be hardcoded instead of relying on a registry or a DirectShow component.
The only workaround I can think of would be to tell WMP to open "file.mpg" instead of "file.vob" while hooking Kernel32.dll!CreateFile() so that it will actually open the real "file.vob". This a hack but it should work. See my FAQ for API hooking techniques.
-- // Alessandro Angeli // MVP :: DirectShow / MediaFoundation // mvpnews at riseoftheants dot com // http://www.riseoftheants.com/mmx/faq.htm
|
|
We do have FFdShow but I'm afraid I don't understand your code (cFile := "wmpdvd://Z/1/1?contentdir="+cPath - ?????). Could you possible translate to C or VB please? Also, do you mean the video file must actually exist in the root of a drive?
"AUGE_OHR" wrote:
[Quoted Text] > hi, > > > Is there a way to play VOB files copied from a DVD to the HD using the WMP > > ActiveX control WITHOUT changing the file extensions to .mpg? > > Yes, if you have a Codec like FFdShow : > *** snip *** > CASE ".VOB" $ UPPER(cFile) // Video-DVD > nPosi := RAT("\",cFile) > IF nPosi > 0 > cPath := UPPER(LEFT(cFile,nPosi - 1)) > cFile := "wmpdvd://Z/1/1?contentdir="+cPath > cFiles[ i ] := cFile > ENDIF > *** EOF *** > but if i remember right "cPATH" must be a "Root" like "Z:\" > > greetings by OHR > Jimmy > > >
|
|
From: "ejm3"
[Quoted Text] > We do have FFdShow but I'm afraid I don't understand your > code (cFile := "wmpdvd://Z/1/1?contentdir="+cPath - > ?????). Could you possible translate to C or VB please? > Also, do you mean the video file must actually exist in > the root of a drive?
That code simply uses the WMPDVD URL protocol to play a DVD structure, not an individual VOB file.
-- // Alessandro Angeli // MVP :: DirectShow / MediaFoundation // mvpnews at riseoftheants dot com // http://www.riseoftheants.com/mmx/faq.htm
|
|
I read you hooking FAQ and I'm sure I don't really understand it but from what I can gleen hooking actually temporarily substitutes a system entry point with a local one - correct? So you are suggesting that WMP uses (at some point) a call to CreateFile or OpenFile and if I hook that function I can then do the bait and switch. However, this is a system wide change correct? How man times a second do you think OpenFile is called on an average machine? Even if I immediated unhook after calling the play method, isn't that a bit risky?
"Alessandro Angeli" wrote:
[Quoted Text] > From: "ejm3" > > > Well, I have personally tested a VOB file and confirmed > > that with a file extension of .vob it loads in both the > > standalong WMP and the ActiveX control and appears to > > play but no video or audio is rendered i.e. black screen > > and no audio. If the extension is changed to .mpg it > > appears to play normally. No errror messages are > > displayed in either case. > > What do you know? They made WMP "smarter" :-) It looks like > now WMP forcefully renders .VOB files with the DVD graph > builder and this choice seems to be hardcoded instead of > relying on a registry or a DirectShow component. > > The only workaround I can think of would be to tell WMP to > open "file.mpg" instead of "file.vob" while hooking > Kernel32.dll!CreateFile() so that it will actually open the > real "file.vob". This a hack but it should work. See my FAQ > for API hooking techniques. > > -- > // Alessandro Angeli > // MVP :: DirectShow / MediaFoundation > // mvpnews at riseoftheants dot com > // http://www.riseoftheants.com/mmx/faq.htm > > >
|
|
From: "ejm3"
[Quoted Text] > I read you hooking FAQ and I'm sure I don't really > understand it but from what I can gleen hooking actually > temporarily substitutes a system entry point with a local > one - correct?
Yes.
> So you are suggesting that WMP uses (at > some point) a call to CreateFile or OpenFile and if I
WMP is a user-mode process so, like any other user-mode process, to open a file it must ask the kernel to do it through Kernel32.dll!CreateFile() (there a couple more entrypoints, but well-behaved processes either use CreateFileA() or CreateFileW()).
> However, this is a system wide change correct?
No, it's not. User-mode hooks are a per-process change (hence not even per application, but per running application instance).
> How man > times a second do you think OpenFile is called on an > average machine? Even if I immediated unhook after > calling the play method, isn't that a bit risky?
I suggested API hooking because it all happens inside your process, without system-wide side effects.
-- // Alessandro Angeli // MVP :: DirectShow / MediaFoundation // mvpnews at riseoftheants dot com // http://www.riseoftheants.com/mmx/faq.htm
|
|
Alessandro,
I'm still quite wary of the nature of what you are talking about. Remember, I'm talking about a VB6 project that is using the WMP ActiveX control. Is this not running then in my applications memory space? I'm assuming I can hook my own memory space also.
In any case, your FAQ is still not at all clear to me. Is there a way we could continue this offline somehow? I would need some serious help including some clear examples tailored to VB6. Can this actually be done in VB6?
John
"Alessandro Angeli" wrote:
[Quoted Text] > From: "ejm3" > > > I read you hooking FAQ and I'm sure I don't really > > understand it but from what I can gleen hooking actually > > temporarily substitutes a system entry point with a local > > one - correct? > > Yes. > > > So you are suggesting that WMP uses (at > > some point) a call to CreateFile or OpenFile and if I > > WMP is a user-mode process so, like any other user-mode > process, to open a file it must ask the kernel to do it > through Kernel32.dll!CreateFile() (there a couple more > entrypoints, but well-behaved processes either use > CreateFileA() or CreateFileW()). > > > However, this is a system wide change correct? > > No, it's not. User-mode hooks are a per-process change > (hence not even per application, but per running application > instance). > > > How man > > times a second do you think OpenFile is called on an > > average machine? Even if I immediated unhook after > > calling the play method, isn't that a bit risky? > > I suggested API hooking because it all happens inside your > process, without system-wide side effects. > > -- > // Alessandro Angeli > // MVP :: DirectShow / MediaFoundation > // mvpnews at riseoftheants dot com > // http://www.riseoftheants.com/mmx/faq.htm > > >
|
|
From: "ejm3"
[Quoted Text] > I'm still quite wary of the nature of what you are > talking about. Remember, I'm talking about a VB6 project
You didn't say it was VB6 before.
> that is using the WMP ActiveX control. Is this not > running then in my applications memory space? I'm > assuming I can hook my own memory space also.
Memory space and process are practically the same on Windows. WMP and all DLLs are an in-process components. Code executed in the context of a given process can access anything loaded in the memory space of that process.
> In any case, your FAQ is still not at all clear to me. Is > there a way we could continue this offline somehow? I
Do you mean offline as in face-to-face (or phone-to-phone) or as in private email or IM? If the latter, I'd rather continue the discussion public on this group. Besides, I usually reply faster to Usenet posts than I do by email. In any case, my email address is spelled out in my signature (please DO NOT write it in clear text on any part of a Usenet message).
> would need some serious help including some clear > examples tailored to VB6. Can this actually be done in > VB6?
I think it can be done, but I can't be sure since I don't use VB6. If you can write callback functions that you can pass to Win32 APIs, than it should work.
Notice that API hooking is a sort of low-level machine-code hacking (it's what user-mode rootkits use). But I can't think of any other way to work around this stupid behavior of WMP's.
-- // Alessandro Angeli // MVP :: DirectShow / MediaFoundation // mvpnews at riseoftheants dot com // http://www.riseoftheants.com/mmx/faq.htm
|
|
OK - let's continue here.
I understand the concept of actually injecting/overwriting the memory/process space of my own application. Let's see if we can develop a step by step recipe of how to go about it. Then I'll post some VB code to see if I've got it right.
Currently I have something like:
Case mtWindowsVideo ClearStage OpenCurtain With wmpStage .uiMode = "none" .URL = strFilePath .Enabled = True .Visible = True .settings.volume = 100 .stretchToFit = False ResizeWindowsVideo .Controls.Play End With
This would be modified like this:
Case mtWindowsVideo ClearStage OpenCurtain With wmpStage .uiMode = "none" .URL = strFilePath .Enabled = True .Visible = True .settings.volume = 100 .stretchToFit = False ResizeWindowsVideo HookCreatFile .Controls.Play UnhookCreateFile End With
Now, HookCreateFile and UnhookCreateFile would be:
HookCreateFile - save current memory state - find where to inject hook - read in some external DLL written in C that actually does the bait and switch with CreateFile() - copy actual bytes of the read in external DLL into current memory space at correct location
UnhookCreateFile - restore saved memory state - perform any miscelaneous cleanup
Now, I'm able to create callback funcitons in VB having done it before. I also know enough to be able to read in a DLL and use memcpy to inject it somewhere. Otherwise, I'm lost...
"Alessandro Angeli" wrote:
[Quoted Text] > From: "ejm3" > > > I'm still quite wary of the nature of what you are > > talking about. Remember, I'm talking about a VB6 project > > You didn't say it was VB6 before. > > > that is using the WMP ActiveX control. Is this not > > running then in my applications memory space? I'm > > assuming I can hook my own memory space also. > > Memory space and process are practically the same on > Windows. WMP and all DLLs are an in-process components. Code > executed in the context of a given process can access > anything loaded in the memory space of that process. > > > In any case, your FAQ is still not at all clear to me. Is > > there a way we could continue this offline somehow? I > > Do you mean offline as in face-to-face (or phone-to-phone) > or as in private email or IM? If the latter, I'd rather > continue the discussion public on this group. Besides, I > usually reply faster to Usenet posts than I do by email. In > any case, my email address is spelled out in my signature > (please DO NOT write it in clear text on any part of a > Usenet message). > > > would need some serious help including some clear > > examples tailored to VB6. Can this actually be done in > > VB6? > > I think it can be done, but I can't be sure since I don't > use VB6. If you can write callback functions that you can > pass to Win32 APIs, than it should work. > > Notice that API hooking is a sort of low-level machine-code > hacking (it's what user-mode rootkits use). But I can't > think of any other way to work around this stupid behavior > of WMP's. > > > -- > // Alessandro Angeli > // MVP :: DirectShow / MediaFoundation > // mvpnews at riseoftheants dot com > // http://www.riseoftheants.com/mmx/faq.htm > > >
|
|
hi,
did you ever try to run a AVIsynth Script File with VOB ?
WMP v6.4 can run AVIsynth "direct" while for WMP v9/v10 you need "MakeAVI" to make some (very) small AVI Container.
Now using FFDshow you can play VOB "by Frame" if you want e.g. for a Cutter Timelist and let them play by your activeX WMPlayer Application ...
greetings by OHR Jimmy
|
|
Jimmy,
Thanks for the help but I have absolutely no idea what you talking about. Please explain.
John
"AUGE_OHR" wrote:
[Quoted Text] > hi, > > did you ever try to run a AVIsynth Script File with VOB ? > > WMP v6.4 can run AVIsynth "direct" while for WMP v9/v10 > you need "MakeAVI" to make some (very) small AVI Container. > > Now using FFDshow you can play VOB "by Frame" if you > want e.g. for a Cutter Timelist and let them play by your > activeX WMPlayer Application ... > > greetings by OHR > Jimmy > > >
|
|
hi,
[Quoted Text] > Thanks for the help but I have absolutely no idea what you talking about. > Please explain.
a VOB File does have a lot of Frames. Using DGIndex or other Tool you can make a Table of all Frames.
AVIsynth is a FrameServer. With AVISynth you can make a Script to play it "Frame by Frame" using DirectShow.
WMP v6.4 can "direct" play AVIsynth Script Files. For WMP v9/v10/v11 you have to convert AVIsynth Script to a AVI Container and than you can play it ... or use VirtualDub.exe to "cut it" ... or ULeadMediaStudio ...
so google for AVISynth and look what it can do for you.
greetings by OHR Jimmy
|
|
Well, thanks for the idea but it is not an option to modify the file in any way. Our clients will copy the file from a DVD to a hard drive and that's it.
"AUGE_OHR" wrote:
[Quoted Text] > hi, > > > Thanks for the help but I have absolutely no idea what you talking about. > > Please explain. > > a VOB File does have a lot of Frames. Using DGIndex or other > Tool you can make a Table of all Frames. > > AVIsynth is a FrameServer. With AVISynth you can make > a Script to play it "Frame by Frame" using DirectShow. > > WMP v6.4 can "direct" play AVIsynth Script Files. For WMP v9/v10/v11 > you have to convert AVIsynth Script to a AVI Container and than you can > play it ... or use VirtualDub.exe to "cut it" ... or ULeadMediaStudio ... > > so google for AVISynth and look what it can do for you. > > greetings by OHR > Jimmy > > >
|
|
From: "ejm3"
HookCreatFile ..Controls.Play *** WAIT FOR play() TO COMPLETE *** UnhookCreateFile
[Quoted Text] > HookCreateFile > - save current memory state
There isn't much to save. If you use a hooking library like Detours, it will do it for you(it's just 5 bytes actually).
> - find where to inject hook
The memory address of the function you want to replace (Kernel32.dll!CreateFileW()).
> - read in some external DLL written in C that actually > does the bait and switch with CreateFile()
If you do it yourself, you don't even need to LoadLibrary() some other DLL.
> - copy actual bytes of the read in external DLL into > current memory space at correct location
Not exactly. Overwrite the prolog of the function you want to hook with a the memory address of your own function (which is nothing more than a callback).
To get details with sample code, read Q13 in my FAQ. If you want to use Detours, take a look at Q12 (and read the license requirements for Detours: http://research.microsoft.com/sn/detours/) and be warned that the Detours API changed, but the steps are mostly the same.
To be able to use the technique in Q12, you need to be able to get the memory address of a callback function implemented in VB6.
-- // Alessandro Angeli // MVP :: DirectShow / MediaFoundation // mvpnews at riseoftheants dot com // http://www.riseoftheants.com/mmx/faq.htm
|
|
oops - I can't wait for play() to complete - at least not in the main thread as I must remain user interactive (and it is way beyond the scope of changes I want to make to run WMP in a seperate thread). I respond to an EndOfStream (or something like that) callback from the WMP...
looking at Detours package...
"Alessandro Angeli" wrote:
[Quoted Text] > From: "ejm3" > > HookCreatFile > ..Controls.Play > *** WAIT FOR play() TO COMPLETE *** > UnhookCreateFile > > > HookCreateFile > > - save current memory state > > There isn't much to save. If you use a hooking library like > Detours, it will do it for you(it's just 5 bytes actually). > > > - find where to inject hook > > The memory address of the function you want to replace > (Kernel32.dll!CreateFileW()). > > > - read in some external DLL written in C that actually > > does the bait and switch with CreateFile() > > If you do it yourself, you don't even need to LoadLibrary() > some other DLL. > > > - copy actual bytes of the read in external DLL into > > current memory space at correct location > > Not exactly. Overwrite the prolog of the function you want > to hook with a the memory address of your own function > (which is nothing more than a callback). > > To get details with sample code, read Q13 in my FAQ. If you > want to use Detours, take a look at Q12 (and read the > license requirements for Detours: > http://research.microsoft.com/sn/detours/) and be warned > that the Detours API changed, but the steps are mostly the > same. > > To be able to use the technique in Q12, you need to be able > to get the memory address of a callback function implemented > in VB6. > > > -- > // Alessandro Angeli > // MVP :: DirectShow / MediaFoundation > // mvpnews at riseoftheants dot com > // http://www.riseoftheants.com/mmx/faq.htm > > >
|
|
From: "ejm3"
[Quoted Text] > oops - I can't wait for play() to complete - at least not > in the main thread as I must remain user interactive (and > it is way beyond the scope of changes I want to make to > run WMP in a seperate thread). I respond to an > EndOfStream (or something like that) callback from the > WMP...
That's ok. Simply do not remove the hook then or remove it when the right openState event fires. Or you can remove the hook in your own hook, after the real CreateFileW() returns. Of course, you should be extremely careful in case CreateFile() is also called by some other thread for other resons during the hooking/unhooking. It is usually a good idea to hook when the application starts and to unhook when the application ends, during "safe" moments. In this case, you can simply keep a flag to signal the hook when it should activate and deactivate.
-- // Alessandro Angeli // MVP :: DirectShow / MediaFoundation // mvpnews at riseoftheants dot com // http://www.riseoftheants.com/mmx/faq.htm
|
|
What's the difference between hook/unhook and activate/deactivate?
"Alessandro Angeli" wrote:
[Quoted Text] > From: "ejm3" > > > oops - I can't wait for play() to complete - at least not > > in the main thread as I must remain user interactive (and > > it is way beyond the scope of changes I want to make to > > run WMP in a seperate thread). I respond to an > > EndOfStream (or something like that) callback from the > > WMP... > > That's ok. Simply do not remove the hook then or remove it > when the right openState event fires. Or you can remove the > hook in your own hook, after the real CreateFileW() returns. > Of course, you should be extremely careful in case > CreateFile() is also called by some other thread for other > resons during the hooking/unhooking. It is usually a good > idea to hook when the application starts and to unhook when > the application ends, during "safe" moments. In this case, > you can simply keep a flag to signal the hook when it should > activate and deactivate. > > > -- > // Alessandro Angeli > // MVP :: DirectShow / MediaFoundation > // mvpnews at riseoftheants dot com > // http://www.riseoftheants.com/mmx/faq.htm > > >
|
|
From: "ejm3"
[Quoted Text] > What's the difference between hook/unhook and > activate/deactivate?
A hook typically performs some operations before or after calling the real function. You can leave the hook in place even when you do not need it, just signal to it that it should call the real function without doing anything else.
-- // Alessandro Angeli // MVP :: DirectShow / MediaFoundation // mvpnews at riseoftheants dot com // http://www.riseoftheants.com/mmx/faq.htm
|
|
|