puhitaku / mtplvcap

Nikon to USB Webcam. Supports older models that Nikon WU does not. Windows/macOS/Linux. No HDMI capture dongle is needed. Ask me on Twitter @puhitaku
https://twitter.com/puhitaku
Other
251 stars 17 forks source link

How did you do this? #81

Closed korpe1 closed 5 months ago

korpe1 commented 5 months ago

How did you do this? I mean, AFAIK Nikon USB interface is propietary. And even "USB mini type B" connector is propietary... So, how do you figured it out without any docs?

puhitaku commented 5 months ago

Now it's time to unveil the secret gem ... which is not that secret haha The source I found and learned so many things from is listed in the Credit section of the readme.

go-mtpfs

mtplvcap started from forking go-mtpfs which implements MTP communication over famous libusb. This software is awesome not only for implementing MTP, but having const.go that contains so many consts extracted from libmtp. munge.py converts a header in libmtp into a Go code.

So why consts are awesome? Please take a look at this line for example. OC stands for "operation code" so you can make an operation call with this enum. You'll easily guess what's going to happen by to call OC_NIKON_StartLiveView!

MTP devices have "properties" that can be read and written. The ID of them is called DPC (device property code) and these are also listed in the same file.

So the primitive things mtplvcap do here are: call commands and read/write properties described in const.go. I did some guessing game here with some trivial try-and-errors to open the shutter and take LV frames.

digiCamControl

Simple operations like opening the shutter and fetching the frame stream were done pretty easily. Painful parts were left next; 1. to control so many knobs on the DSLR like exposure and f-value. 2. to handle the difference of so many models ranging from 2000s to 2020s.

Implementing all of them without knowledge was impossible. So, I looked for other implementations that do the things. One of them was digiCamControl that covers massive number of DSLRs so I learned so many from here.

Experiment and contribution

All I had was a Nikon D5300 then so I went to a camera store to test my program. Luckily, a store clerk allowed me to do so (not knowing I'm doing some dev ... I never lied, but I said "I want to try tethered shot" lol). The confirmed model list in readme with my name other than D5300 was all tested in the store.

And of course, mtplvcap would have never grown like today without contributions from all over the world. Issue author and I tried so many things so get it working.

korpe1 commented 5 months ago

digiCamControl

Simple operations like opening the shutter and fetching the frame stream were done pretty easily. Painful parts were left next; 1. to control so many knobs on the DSLR like exposure and f-value. 2. to handle the difference of so many models ranging from 2000s to 2020s.

Implementing all of them without knowledge was impossible. So, I looked for other implementations that do the things. One of them was digiCamControl that covers massive number of DSLRs so I learned so many from here.

How did digiCamControl implemented this propietary protocol without docs?

puhitaku commented 5 months ago

I'm not sure, but I think some reverse-engineering like sniffing API calls between the official tool and camera is possible because MTP is well-known especially in Windows world.

korpe1 commented 5 months ago

I'm not sure, but I think some reverse-engineering like sniffing API calls between the official tool and camera is possible because MTP is well-known especially in Windows world.

Okay, thank you for your answers :) Have a nice weekend!