clvLabs / PyATEMMax

A Python library to monitor and control Blackmagic Design ATEM video switchers.
https://clvlabs.github.io/PyATEMMax/
GNU General Public License v3.0
77 stars 20 forks source link

Uploading images to the ATEM Switcher #20

Open TerryHewitt opened 2 years ago

TerryHewitt commented 2 years ago

I have an ATEM Mini and I would like to populate the 20 still images buffer with images. I can't see a function to upload the image. Have I missed it?

If I haven't I'm happy to have a go and add it to the library.

Best wishes Terry

clvLabs commented 2 years ago

Hi Terry,

I've trying to implement it because of a previous request I've received... with no luck 😢

I tried to use libqatemcontrol as a reference but the switcher I have at hand responds with messages that not fit into libqatemcontrol's message definitions.

It would be very nice from you to submit a pull request if you can do something about it.

Thanks!!

TerryHewitt commented 2 years ago

Thanks for the reply.

Yes, happy to have a go.

Would you also be happy sharing your 'attempted' code - to get me started?

Best wishes Terry

clvLabs commented 2 years ago

Thanks a lot for the help, Terry!

I've just created a new branch for the issue: 20-uploading-images-to-the-atem-switcher and pushed the work in progress commits I had.

Basically, I was trying to emulate the libqatemcontrol library. The reason for choosing this one is that in the unofficial reverse engineered BMD protocol PyATEMMax is based on, Kasper Skårhøj himself recommends it for uploading clips and stills.

You will find this code is not yet ready to be merged into master, even if it worked:

If you succeed in making this work, we'll do a little cleanup before merging.

List of changes

I'll go through the list of changes to explain what I changed in each commit:

a765ac0 - Scraped new command IDs from wireshark-atem-dissector / libqatemcontrol

In this commit I could get a few unknown command names from libqatemcontrol and wireshark-atem-dissector.

PyATEMMax/ATEMProtocol.py

No useful code added, just nice descriptions for commands that won't be processed (because their message structure is unknown/undocumented).

8ef62a6 - File transfer WIP

In this commit I tried to implement the client/switcher commands that I could see libqatemcontrol using for its file transfers.

Inside libqatemcontrol:

As an example, to see the payload structure for the FTSU (Data Transfer Request) command I found a requestData() method in QAtemConnection which filled the command fields, revealing the packet structure (see requestData() code).

PyATEMMax/ATEMProtocol.py

Moved the following commands from the not implemented to the implemented section:

PyATEMMax/ATEMCommandHandlers.py

Implemented the parsing of the switcher side commands (notifications to the client):

PyATEMMax/ATEMSetterMethods.py

Implemented the construction of the client side commands (requests to the switcher):

65a6318 - TEMPORARY: use events.py to test

In this commit I tried to follow the qatemuploader example using the new commands (sadly, with no luck).

I'm using the events.py library example as a temporary placeholder for the test code, it will be restored to its original state before merging.

examples/events.py

67bf8ba - Fix names of FTSD/FTSU

It seems I forgot removing the Not implemented text from FTSU/FTSD and I found out while writing this text. This commit fixes that :)

0b28078 - Add tmp-dev-utils (TEMPORARY)

In this commit I upload the utilities I'm using to study the communications with the switcher (see below).

The problem

In the events.py example, I first try a sendAcquireMediaLock() with:

After that, I should wait for a LKOB or LKST but I'm getting away with a time.sleep(1) because I can see hex logs ;)

Then, I do a sendInitDownloadToSwitcherRequest() with:

After that the rest of code is commented, I suppose because the response from the switcher was not the expected at this point. Honestly... I tried this about 6 months ago and some details got lost in the way.

The debug tools

For all these tests, the stdout hex dump offered by the DEBUG logging activated in 65a6318 was not enough. I soon found myself pausing the console output to wrap my head around a stream of hex representations of messages to understand what was happening, and you know that's not good for human brains :)

So, my first attempt was to create a switcher-spy, some kind of proxy with the ability to capture the traffic between a client and a switcher and save it to a log file.

The idea was to use it to record the conversation between the official ATEM client software and the switcher when an image was uploaded, so I could inspect those huge hex streams or even create a log reader to make it a bit easier.

The result are huge jsonl files (see jsonlines.org) with never-ending lines of brain-killing hex values. A log-reader was mandatory.

I would have loved to reuse the parser from the library, but... when starting the project I decided to follow the code structure of the original library to make the porting process easier. A refactor is an option I've been evaluating but I don't have that kind of time right now, so I kind of reprogrammed the ATEM message parsing in the log-reader.

Both utilities are now uploaded to the repo in a tmp-dev-utils folder that we'll remove before merging (the idea is to release them after that refactor I talked about).

The end

... and I think that's it !

Sorry for the loooooong answer, but I didn't want to leave anything behind, as you're being so kind to offer your help.

Thanks again, and please let me know if you have any doubts.

TerryHewitt commented 2 years ago

Thanks.

I’ll download it, and have a look at it over the next couple of weeks, then I’ll get back to you.

Best wishes

Terry

Professor W T Hewitt

WTH Associates Ltd

Telephone: +44 7905 759 003

Company registration number:7336226

HMRC VAT Registration number: 998 8457 23

Company Registered Address

St George's House | 215 - 219 Chester Road | Manchester | M15 4JE

From: clvLabs @.> Sent: 18 August 2022 01:33 To: clvLabs/PyATEMMax @.> Cc: Terry Hewitt @.>; Author @.> Subject: Re: [clvLabs/PyATEMMax] Uploading images to the ATEM Switcher (Issue #20)

Thanks a lot for the help, Terry!

I've just created a new branch for the issue: 20-uploading-images-to-the-atem-switcher https://github.com/clvLabs/PyATEMMax/tree/20-uploading-images-to-the-atem-switcher and pushed the work in progress commits I had.

Basically, I was trying to emulate the libqatemcontrol https://github.com/petersimonsson/libqatemcontrol library. The reason for choosing this one is that in the unofficial reverse engineered BMD protocol http://skaarhoj.com/fileadmin/BMDPROTOCOL.html PyATEMMax is based on, Kasper Skårhøj himself recommends it for uploading clips and stills.

You will find this code is not yet ready to be merged into master, even if it worked:

If you succeed in making this work, we'll do a little cleanup before merging.

List of changes

I'll go through the list of changes https://github.com/clvLabs/PyATEMMax/compare/master...20-uploading-images-to-the-atem-switcher to explain what I changed in each commit:

https://github.com/clvLabs/PyATEMMax/commit/a765ac0d3ae1e61912fc47c18edd3ce9b9248822 a765ac0 - Scraped new command IDs from wireshark-atem-dissector / libqatemcontrol

In this commit I could get a few unknown command names from libqatemcontrol https://github.com/petersimonsson/libqatemcontrol and wireshark-atem-dissector https://github.com/peschuster/wireshark-atem-dissector .

PyATEMMax/ATEMProtocol.py

No useful code added, just nice descriptions for commands that won't be processed (because their message structure is unknown/undocumented).

https://github.com/clvLabs/PyATEMMax/commit/8ef62a678ff384aec341dee2a19f51ab36b4771b 8ef62a6 - File transfer WIP

In this commit I tried to implement the client/switcher commands that I could see libqatemcontrol using for its file transfers.

Inside libqatemcontrol:

As an example, to see the payload structure for the FTSU (Data Transfer Request) command I found a requestData() method in QAtemConnection which filled the command fields, revealing the packet structure (see requestData() code https://github.com/petersimonsson/libqatemcontrol/blob/252b0319fabf291a90d791bddc7619c2ebf0b095/qatemconnection.cpp#L1496 ).

PyATEMMax/ATEMProtocol.py

Moved the following commands from the not implemented to the implemented section:

PyATEMMax/ATEMCommandHandlers.py

Implemented the parsing of the switcher side commands (notifications to the client):

PyATEMMax/ATEMSetterMethods.py

Implemented the construction of the client side commands (requests to the switcher):

In this commit I tried to follow the qatemuploader example using the new commands (sadly, with no luck).

I'm using the events.py library example as a temporary placeholder for the test code, it will be restored to its original state before merging.

examples/events.py

It seems I forgot removing the Not implemented text from FTSU/FTSD and I found out while writing this text. This commit fixes that :)

https://github.com/clvLabs/PyATEMMax/commit/0b28078b76b156a51091c045a5adb768571804c4 0b28078 - Add tmp-dev-utils (TEMPORARY)

In this commit I upload the utilities I'm using to study the communications with the switcher (see below).

The problem

In the events.py example, I first try a sendAcquireMediaLock() with:

After that, I should wait for a LKOB or LKST but I'm getting away with a time.sleep(1) because I can see hex logs ;)

Then, I do a sendInitDownloadToSwitcherRequest() with:

After that the rest of code is commented, I suppose because the response from the switcher was not the expected at this point. Honestly... I tried this about 6 months ago and some details got lost in the way.

The debug tools

For all these tests, the stdout hex dump offered by the DEBUG logging activated in 65a6318 was not enough. I soon found myself pausing the console output to wrap my head around a stream of hex representations of messages to understand what was happening, and you know that's not good for human brains :)

So, my first attempt was to create a switcher-spy, some kind of proxy with the ability to capture the traffic between a client and a switcher and save it to a log file.

The idea was to use it to record the conversation between the official ATEM client software and the switcher when an image was uploaded, so I could inspect those huge hex streams or even create a log reader to make it a bit easier.

The result are huge jsonl files (see jsonlines.org https://jsonlines.org/ ) with never-ending lines of brain-killing hex values. A log-reader was mandatory.

I would have loved to reuse the parser from the library, but... when starting the project I decided to follow the code structure of the original library to make the porting process easier. A refactor is an option I've been evaluating but I don't have that kind of time right now, so I kind of reprogrammed the ATEM message parsing in the log-reader.

Both utilities are now uploaded to the repo in a tmp-dev-utils folder that we'll remove before merging (the idea is to release them after that refactor I talked about).

The end

... and I think that's it !

Sorry for the loooooong answer, but I didn't want to leave anything behind, as you're being so kind to offer your help.

Thanks again, and please let me know if you have any doubts.

— Reply to this email directly, view it on GitHub https://github.com/clvLabs/PyATEMMax/issues/20#issuecomment-1218768701 , or unsubscribe https://github.com/notifications/unsubscribe-auth/ADX3D45IOQCLBLJTU4BEA3DVZWAENANCNFSM5TTTZ2JA . You are receiving this because you authored the thread. https://github.com/notifications/beacon/ADX3D452DL42V62KQHYPWDLVZWAENA5CNFSM5TTTZ2JKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOJCSO6PI.gif Message ID: @. @.> >

TerryHewitt commented 2 years ago

A status update….

I’ve downloaded the code from Github.

Printed out the documentation and the listings I want handy

From qatemconnection.cpp https://github.com/petersimonsson/libqatemcontrol/blob/master/qatemconnection.cpp and qatemuploader.cpp https://github.com/petersimonsson/libqatemcontrol/blob/master/example/qatemuploader/qatemuploader.cpp figured out and understand the algorithm

Made an UploadTest.py as a development vehicle and eventually a program for examples.

UploadTest works – except the UploadToSwitcher is not doing anything useful yet of course.

These commands need implementing

'FTDa': 'Data Transfer Data', 'FTCD': 'Data Transfer Upload Continue', 'FTDC': 'Data Transfer Completed',' 'FTFD': 'Data File Description',

Done _handleFTDC and _handleFTCD but NOT tested either

Other two are ‘output’ only so will be implemented in below functions

So need to implement

Test it all.

Another update in a week or so.

By the way whats your name? can’t keep calling you clvlabs!

Best wishes

Terry

Professor W T Hewitt

WTH Associates Ltd

Telephone: +44 7905 759 003

Company registration number:7336226

HMRC VAT Registration number: 998 8457 23

Company Registered Address

St George's House | 215 - 219 Chester Road | Manchester | M15 4JE

From: clvLabs @.> Sent: 18 August 2022 01:33 To: clvLabs/PyATEMMax @.> Cc: Terry Hewitt @.>; Author @.> Subject: Re: [clvLabs/PyATEMMax] Uploading images to the ATEM Switcher (Issue #20)

Thanks a lot for the help, Terry!

I've just created a new branch for the issue: 20-uploading-images-to-the-atem-switcher https://github.com/clvLabs/PyATEMMax/tree/20-uploading-images-to-the-atem-switcher and pushed the work in progress commits I had.

Basically, I was trying to emulate the libqatemcontrol https://github.com/petersimonsson/libqatemcontrol library. The reason for choosing this one is that in the unofficial reverse engineered BMD protocol http://skaarhoj.com/fileadmin/BMDPROTOCOL.html PyATEMMax is based on, Kasper Skårhøj himself recommends it for uploading clips and stills.

You will find this code is not yet ready to be merged into master, even if it worked:

If you succeed in making this work, we'll do a little cleanup before merging.

List of changes

I'll go through the list of changes https://github.com/clvLabs/PyATEMMax/compare/master...20-uploading-images-to-the-atem-switcher to explain what I changed in each commit:

https://github.com/clvLabs/PyATEMMax/commit/a765ac0d3ae1e61912fc47c18edd3ce9b9248822 a765ac0 - Scraped new command IDs from wireshark-atem-dissector / libqatemcontrol

In this commit I could get a few unknown command names from libqatemcontrol https://github.com/petersimonsson/libqatemcontrol and wireshark-atem-dissector https://github.com/peschuster/wireshark-atem-dissector .

PyATEMMax/ATEMProtocol.py

No useful code added, just nice descriptions for commands that won't be processed (because their message structure is unknown/undocumented).

https://github.com/clvLabs/PyATEMMax/commit/8ef62a678ff384aec341dee2a19f51ab36b4771b 8ef62a6 - File transfer WIP

In this commit I tried to implement the client/switcher commands that I could see libqatemcontrol using for its file transfers.

Inside libqatemcontrol:

As an example, to see the payload structure for the FTSU (Data Transfer Request) command I found a requestData() method in QAtemConnection which filled the command fields, revealing the packet structure (see requestData() code https://github.com/petersimonsson/libqatemcontrol/blob/252b0319fabf291a90d791bddc7619c2ebf0b095/qatemconnection.cpp#L1496 ).

PyATEMMax/ATEMProtocol.py

Moved the following commands from the not implemented to the implemented section:

PyATEMMax/ATEMCommandHandlers.py

Implemented the parsing of the switcher side commands (notifications to the client):

PyATEMMax/ATEMSetterMethods.py

Implemented the construction of the client side commands (requests to the switcher):

In this commit I tried to follow the qatemuploader example using the new commands (sadly, with no luck).

I'm using the events.py library example as a temporary placeholder for the test code, it will be restored to its original state before merging.

examples/events.py

It seems I forgot removing the Not implemented text from FTSU/FTSD and I found out while writing this text. This commit fixes that :)

https://github.com/clvLabs/PyATEMMax/commit/0b28078b76b156a51091c045a5adb768571804c4 0b28078 - Add tmp-dev-utils (TEMPORARY)

In this commit I upload the utilities I'm using to study the communications with the switcher (see below).

The problem

In the events.py example, I first try a sendAcquireMediaLock() with:

After that, I should wait for a LKOB or LKST but I'm getting away with a time.sleep(1) because I can see hex logs ;)

Then, I do a sendInitDownloadToSwitcherRequest() with:

After that the rest of code is commented, I suppose because the response from the switcher was not the expected at this point. Honestly... I tried this about 6 months ago and some details got lost in the way.

The debug tools

For all these tests, the stdout hex dump offered by the DEBUG logging activated in 65a6318 was not enough. I soon found myself pausing the console output to wrap my head around a stream of hex representations of messages to understand what was happening, and you know that's not good for human brains :)

So, my first attempt was to create a switcher-spy, some kind of proxy with the ability to capture the traffic between a client and a switcher and save it to a log file.

The idea was to use it to record the conversation between the official ATEM client software and the switcher when an image was uploaded, so I could inspect those huge hex streams or even create a log reader to make it a bit easier.

The result are huge jsonl files (see jsonlines.org https://jsonlines.org/ ) with never-ending lines of brain-killing hex values. A log-reader was mandatory.

I would have loved to reuse the parser from the library, but... when starting the project I decided to follow the code structure of the original library to make the porting process easier. A refactor is an option I've been evaluating but I don't have that kind of time right now, so I kind of reprogrammed the ATEM message parsing in the log-reader.

Both utilities are now uploaded to the repo in a tmp-dev-utils folder that we'll remove before merging (the idea is to release them after that refactor I talked about).

The end

... and I think that's it !

Sorry for the loooooong answer, but I didn't want to leave anything behind, as you're being so kind to offer your help.

Thanks again, and please let me know if you have any doubts.

— Reply to this email directly, view it on GitHub https://github.com/clvLabs/PyATEMMax/issues/20#issuecomment-1218768701 , or unsubscribe https://github.com/notifications/unsubscribe-auth/ADX3D45IOQCLBLJTU4BEA3DVZWAENANCNFSM5TTTZ2JA . You are receiving this because you authored the thread. https://github.com/notifications/beacon/ADX3D452DL42V62KQHYPWDLVZWAENA5CNFSM5TTTZ2JKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOJCSO6PI.gif Message ID: @. @.> >

clvLabs commented 2 years ago

Hi Terry, thanks for the update!!

BTW, my name is Tony :)

TerryHewitt commented 2 years ago

Tony,

After that initial spark, I’ve been side tracked, and will be going on holiday in a few days. So I will update you again at the end of September when hopefully I’ve had time to actually do something!

Best wishes

Terry

Professor W T Hewitt

WTH Associates Ltd

Telephone: +44 7905 759 003

Company registration number:7336226

HMRC VAT Registration number: 998 8457 23

Company Registered Address

St George's House | 215 - 219 Chester Road | Manchester | M15 4JE

From: clvLabs @.> Sent: 30 August 2022 20:34 To: clvLabs/PyATEMMax @.> Cc: Terry Hewitt @.>; Author @.> Subject: Re: [clvLabs/PyATEMMax] Uploading images to the ATEM Switcher (Issue #20)

Hi Terry, thanks for the update!!

BTW, my name is Tony :)

— Reply to this email directly, view it on GitHub https://github.com/clvLabs/PyATEMMax/issues/20#issuecomment-1232080947 , or unsubscribe https://github.com/notifications/unsubscribe-auth/ADX3D4ZWEIRO7TEVEDIZJGTV3ZO2TANCNFSM5TTTZ2JA . You are receiving this because you authored the thread. https://github.com/notifications/beacon/ADX3D4ZAHFPS6JSDWL4SAM3V3ZO2TA5CNFSM5TTTZ2JKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOJFYBAMY.gif Message ID: @. @.> >