Giter VIP home page Giter VIP logo

pyatemmax's Introduction

PyATEMMax

A Python library to monitor and control Blackmagic Design ATEM video switchers.

It's a port of the great ATEMmax Arduino library by Kasper Skårhøj.

Documentation

You can find an online version of the documentation at https://clvlabs.github.io/PyATEMMax/

What's in the repo

  • .vscode: Recommended extensions and settings for VS Code.
  • PyATEMMax: Library code.
  • docs: Documentation (using Jekyll and GitHub Pages).
  • examples: Some code examples to get started.

pyatemmax's People

Contributors

clvlabs avatar s-kol-gg avatar sierrax369 avatar slampants avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

pyatemmax's Issues

Chroma Keying - Advanced Settings

Is there a way to set and read advanced upstream key settings like Key Adjustement, Chroma Correction or Color Adjustement of the Upstream Key when using Chroma ?

And if not, is it planned to add this functionality in the future ? 😄

Thanks in advance.

Capture

SuperSource cannot select a video source

Hello,
I have an ATEM Mini Extreme and I want to use PyATEMMax to display multiple sources on the screen. Similar to a quad splitter.
SuperSource is good for this and I've been trying to display a video source for several days now.

With small scripts I made the first attempts to change the position and size of the boxes. It is working.

Here is my test code to display source 1 in box 1:

import PyATEMMax

switcher = PyATEMMax.ATEMMax()
switcher.connect("192.168.178.50")
if switcher.waitForConnection(infinite=False):
switcher.setSuperSourceBoxParametersEnabled(switcher.atem.boxes.box1,1)
switcher.setSuperSourceBoxParametersInputSource(switcher.atem.boxes.box1,switcher.atem.videoSources.input1.value)
switcher.setSuperSourceBoxParametersPositionX(switcher.atem.boxes.box1,-2)
switcher.setSuperSourceBoxParametersPositionY(switcher.atem.boxes.box1,2)
switcher.setSuperSourceBoxParametersSize(switcher.atem.boxes.box1, 0.4)
print("Settings updated")
otherwise:
print("ERROR: no response from switcher")
switcher.disconnect()

Can someone help me out?

Upstreamkey on air at next transition

I see that with "setKeyerOnAirEnabled" you can turn on or off any upstreamkey. But how can I put it on preview? So it would go on live (on air) at the next transition. Plz help.

Unable to use audiomixer API

After connecting to an ATEM and successfully switching video sources, I'm finding I'm unable to control any audio sources, including volume, enable and disable etc.

Some example code I'm using for the audio mixer:

import PyATEMMax
import time
switcher = PyATEMMax.ATEMMax()
switcher.connect("192.168.8.172")
switcher.waitForConnection(infinite=False)

switcher.setAudioMixerInputMixOption(switcher.atem.audioSources.mic1, switcher.atem.audioMixerInputMixOptions.on) # Fails to turn on microphone
switcher.setAudioMixerInputVolume(switcher.atem.audioSources.mic1, 3.0)
print("Mic 1 Volume 1:", switcher.audioMixer.input["mic1"].volume) # Prints 0, when should be 3

time.sleep(1)

switcher.setAudioMixerInputMixOption(switcher.atem.audioSources.mic1, switcher.atem.audioMixerInputMixOptions.off) # Fails to turn off microphone
switcher.setAudioMixerInputVolume(switcher.atem.audioSources.mic1, 0.0)
print("Mic 1 Volume 2:", switcher.audioMixer.input["mic1"].volume) # Prints 0

When viewing the ATEM software control, I can also verify none of the values are changing as expected.

Let me know if I've written the code incorrectly or whether this is an internal bug.

Set Key DVE Fill Source and Position

How can you set the DVE Upstream Key, choose the two cameras, and set position. I am trying to build a Picture in Picture function using this library.

Camera Settings Setup

Hello! This definitely isn't the way you're supposed to use github, but I'm an idiot. I tweaked this function a bunch to get it working neatly with my studio micro 4ks:

def setCameraControlVideomode(self, camera: Union[ATEMConstant, str, int], video_mode: str) -> None:
"""Set Camera Control Video Mode
fps: int, resolution: int, pal_or_ntsc: str, interlaced: int
Args:
camera: see ATEMCameras
fps (int): ?
resolution (int): ?
interlaced (int): ?
"""
# 0= resolution // 1= framerate (approx!) // 2= interlaced ("i" or "p") // 3= NTSC or PAL
video_mode_dict = {
#"f1080i50": (1,3,1,1), #Not supported by camera
#"f525i59_94_ntsc" :
#"f625i_50_pal"
#"f525i59_94_ntsc_16_9"
#"f625i_50_pal_16_9"
#"f1080i23_98": (0,3,1,1),
#"f1080i24": (0,3,1,0),
"f720p50": (3,2,0,0),
"f720p59_94":(4,2,0,1),
"f720p60": (4,2,0,0),
"f1080i25": (1,3,1,0),
"f1080i29_97": (2,3,0,1),
"f1080i30": (2,3,1,0),
"f1080i59_94": (2,3,1,1),
"f1080i60": (2,3,1,0),
"f1080p23_98": (0,3,0,1),
"f1080p24": (0,3,0,0),
"f1080p25": (1,3,0,0),
"f1080p29_97": (2,3,0,1),
"f1080p30": (2,3,0,0),
"f1080p50": (3,3,0,0),
"f1080p59_94": (4,3,0,1),
"f1080p60": (4,3,0,0),
"f2160p23_98": (0,6,0,1),
"f2160p24": (0,6,0,0),
"f2160p25": (1,6,0,0),
"f2160p29_97": (2,6,0,1),
"f2160p30": (2,6,0,0)
}

    camera_val = self.atem.cameras[camera].value

    self.switcher._prepareCommandPacket("CCmd", 24)
    self.switcher._outBuf.setU8(0, camera_val)
    self.switcher._outBuf.setU8(1, 1)
    self.switcher._outBuf.setU8(2, 0)
    self.switcher._outBuf.setU8(4, 0x01)   # Data type: int8
    self.switcher._outBuf.setU8(7, 0x05)   # 5 Byte array
    #self.switcher._outBuf.setU8(9, 0x05)   # 5 byte array
    self.switcher._outBuf.setU8(16, video_mode_dict[video_mode][0])
    self.switcher._outBuf.setU8(17, video_mode_dict[video_mode][3])   # Regular M-rate
    self.switcher._outBuf.setU8(18, video_mode_dict[video_mode][1])
    self.switcher._outBuf.setU8(19, video_mode_dict[video_mode][2])
    self.switcher._outBuf.setU8(20, 0x00)   # YUV
    self.switcher._finishCommandPacket()

Setting macro name & notes

Hi,

Is it possible to set a macro name & note when recording? As far as I can see, this is currently not implemented. In ATEM Software Control, this is implemented before starting recording. I would expect to see this functionality as parameters in execMacroRecord.

DownstreamKeyer setters using the wrong Enum

Hi,

All DownstreamKeyer setters use keyer names e.g. 'keyer1', instead of 'dsk1'. Numeric works fine. The reason is obvious, all use .keyers, and .dsks (or equivalent) does not even exist.

Uploading images to the ATEM Switcher

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

Using auto transition feature

Hello,

I am using PyATEMMax to control a BlackMagic Mini Extreme ISO using a USB remote which works fine so far.

However I am trying to achieve the auto transition that comes with the ATEM Software Control. I am aware of setting the argument to one of the provided ATEMMixEffects but I do not know how to get the smooth fade between two scenes instead of the hard cut.

Thank you for your help!

EDIT: I think I found a solution for my problem. Instead of doing this

switcher.setProgramInputVideoSource(0, camNr)

I executed the AutoME:

switcher.execAutoME(0)

But I am not quite sure what the passed argument of execAutoME does, putting 0 kind of just worked.

switch.setTransitionWipePattern() not working

I when I use wipe pattern set switch.setTransitionWipePattern(0, "leftToRight") it get back an key error Traceback (most recent call last): File "D:/Dokumentumok/py/atem/atem.py", line 19, in <module> btn = Button(root, text = 'Click me !', bd = '5', command =macup()) File "D:/Dokumentumok/py/atem/atem.py", line 16, in macup switch.setTransitionWipePattern(0, "leftToRight") File "C:\Users\halla\AppData\Local\Programs\Python\Python38-32\lib\site-packages\PyATEMMax\ATEMSetterMethods.py", line 381, in setTransitionWipePattern pattern_val = self.atem.patternStyles[pattern] File "C:\Users\halla\AppData\Local\Programs\Python\Python38-32\lib\site-packages\PyATEMMax\ATEMConstant.py", line 76, in __getitem__ found = self.byName(item) File "C:\Users\halla\AppData\Local\Programs\Python\Python38-32\lib\site-packages\PyATEMMax\ATEMConstant.py", line 108, in byName return self._values[name] KeyError: 'leftToRight'

How can I fix it?

Unreliable Connection

I'm so impressed with this module and the functionality you've been able to reverse engineer, thank you so much for making this available.

I'm running into an issue that persists across multiple ATEM devices and operating systems. Sometimes the code connects to the ATEM and sometimes it just endlessly tries (but fails) to connect. My switchers all run firmware 8.1.1 so I understand there may be compatibility problems but the intermittent nature of this issue suggests something more to me.

I've generated some logs that I hope will help troubleshoot using this test code:

import logging

import PyATEMMax

logging.basicConfig(filename='pyatemmax.log', encoding='utf-8', level=logging.DEBUG)

switcher = PyATEMMax.ATEMMax()
switcher.setSocketLogLevel(logging.DEBUG)

switcher.connect("192.168.2.200")
switcher.waitForConnection()
logging.log(logging.INFO, 'Connected')

Attached are a couple sets of logs (from different module versions), one where it successfully connects, and one where it continuously fails to connect:

v1.0b4
pyatemmax-connected.log
pyatemmax-failed.log

1.0b6
pyatemmax-connected-2.log
pyatemmax-failed-2.log

Thanks again, if there's anything I can do to help please let me know!

switcher.downstreamKeyer[].onAir not working

Got a report of the variable not reflecting the real state of the switcher.

Tried it running the scheduled-tasks example and there it was... DSK1 was not changed (when it was in previous versions).

How to set key

Hi maybe wrong way to ask but i am trying to find the correct command to set the key 1 to on
image

Could you tell me on how to do this?

Thanks

setTransitionNextTransition uses incorrect enum

For the existing source it is impossible to set nextTransition to value 6 which is correct, because the value is validated with wrong enum:
nextTransition_val = self.atem.transitionStyles[nextTransition].value
in my case i have fixed in following way:
nextTransition_val = nextTransition
which allows me to set any transition setting i need.

AudioMixer on Current ATEM Devices.

Think I read somewhere in the references, that the Issues like #6 was the result of ATEM Firmware Updates (in 2018?).
Maybe the setAudioMixer* examples from the Documentation like switcher.setAudioMixerMasterVolume(1.8) # Set Master Volume: 1.8dB should removed.

Findings in the docs

Some little findings in the docs

docs/data/protocol

  • The "t" is missing in "swicher" in the complete doc.
  • swicher.atem.switcherPortTypes: Typo. The point "multiviewer" is written with a lower "V"
  • swicher.atem.mixEffects mixEffect1..4: Range. The values are 0..3

docs/logging/

  • switcher.setLogLevel(logging.DEBUG): This loglevel has no effect

docs/methods/exec/

  • execCutME, execAutoME, execFadeToBlackME mE: see ATEMMixEffects: There's no "ATEMMixEffects"-reference in the docs.

docs/methods/set/

  • setCameraControlZoomSpeed zoomSpeed (float): 0.0-1.0: The range of zoom speed values should be -1.0-1.0

docs/examples/scan/

  • for i in range(1,255): The loop should stop at 254

docs/examples/scan-query/

  • The loop should stop at 254 for i in range(1,255):

Returns bool if Upstream Key is on air

I am planning to make a GUI and I would need to know if the Upstream keys are on air or not.Is there a method which returns false or true if maybe on me2 Upstream key1 is on air?

SuperSource reports all boxes at default values

I'm utilizing PyATEMMax in an effort to set SuperSource settings, but I'm also trying to gather the current SuperSource state before making changes.

I have this block of code pulling SuperSource state from my ATEM Mini Extreme ISO:

        for box in range(zboxes):
                zvalues[box] = {}
                zvalues[box]['enabled'] = switcher.superSource.boxParameters[box].enabled
                zvalues[box]['source'] = switcher.superSource.boxParameters[box].inputSource
                zvalues[box]['posx'] = switcher.superSource.boxParameters[box].position.x
                zvalues[box]['posy'] = switcher.superSource.boxParameters[box].position.y
                zvalues[box]['size'] = switcher.superSource.boxParameters[box].size
                zvalues[box]['crop'] = switcher.superSource.boxParameters[box].cropped
                zvalues[box]['croptop'] = switcher.superSource.boxParameters[box].crop.top
                zvalues[box]['cropbottom'] = switcher.superSource.boxParameters[box].crop.bottom
                zvalues[box]['cropleft'] = switcher.superSource.boxParameters[box].crop.left
                zvalues[box]['cropright'] = switcher.superSource.boxParameters[box].crop.right
        pprint.pprint(zvalues)

It gets me this output:

{0: {'crop': False,
     'cropbottom': 0.0,
     'cropleft': 0.0,
     'cropright': 0.0,
     'croptop': 0.0,
     'enabled': False,
     'posx': 0.0,
     'posy': 0.0,
     'size': 0.0,
     'source': PyATEMMax.ATEMProtocolEnums.ATEMConstant(name=, value=None)},
 1: {'crop': False,
     'cropbottom': 0.0,
     'cropleft': 0.0,
     'cropright': 0.0,
     'croptop': 0.0,
     'enabled': False,
     'posx': 0.0,
     'posy': 0.0,
     'size': 0.0,
     'source': PyATEMMax.ATEMProtocolEnums.ATEMConstant(name=, value=None)},
 2: {'crop': False,
     'cropbottom': 0.0,
     'cropleft': 0.0,
     'cropright': 0.0,
     'croptop': 0.0,
     'enabled': False,
     'posx': 0.0,
     'posy': 0.0,
     'size': 0.0,
     'source': PyATEMMax.ATEMProtocolEnums.ATEMConstant(name=, value=None)},
 3: {'crop': False,
     'cropbottom': 0.0,
     'cropleft': 0.0,
     'cropright': 0.0,
     'croptop': 0.0,
     'enabled': False,
     'posx': 0.0,
     'posy': 0.0,
     'size': 0.0,
     'source': PyATEMMax.ATEMProtocolEnums.ATEMConstant(name=, value=None)}}

Which 1) does not match the ATEM configuration (boxes 1 and 2 are enabled, both are scaled, and have non-0,0 positions), and 2) looks an awful lot like default values are being output.

Is this a defect in the module, or am I doing something wrong in gathering these details?

$ pip3 show pyatemmax
Name: PyATEMMax
Version: 1.0b5
Summary: A Python library to monitor and control Blackmagic Design ATEM video switchers.
Home-page: https://github.com/clvLabs/PyATEMMax
Author: Tony Aguilar
Author-email: [email protected]
License: GPL
Location: /home/administrator/.local/lib/python3.6/site-packages
Requires:
$
$ python3 --version
Python 3.6.9

I have not yet tried setting SuperSource parameters -- maintaining a cache of what I've told SuperSource to do would be a viable, though not-preferred workaround.

Happy to share any additional debug data if needed, just let me know what I need to provide.

setInputExternalPortType() does not work

After calling setInputShortName() an [InPr] (Input Properties) is received from the switcher with the changed name.

However, after calling setInputExternalPortType() i haven't received any response from the switcher yet.

The code seems to be doing the same as the original, but I haven't tested it on an Arduino to verify if the original code works with my switcher.

Can't select black as VideoSource

Since switcher.atem.videoSources.black has a value of 0, the "if not foundSrc:" on line 234 of ATEMProtocol.py fails.
Changing to "if foundSrc == None:" fixes it.

Error traceback:
Traceback (most recent call last):
File "mcmode_atem.py", line 130, in
0, switcher.atem.videoSources.black)
File "/home/pi/.local/lib/python3.7/site-packages/PyATEMMax/ATEMSetterMethods.py", line 191, in setProgramInputVideoSource
videoSource_val = self.atem.getVideoSrc(videoSource)
File "/home/pi/.local/lib/python3.7/site-packages/PyATEMMax/ATEMProtocol.py", line 235, in getVideoSrc
raise ATEMException(f"{source} ({type(source)}) is not a valid source")
PyATEMMax.ATEMException.ATEMException: black (<class 'PyATEMMax.ATEMConstant.ATEMConstant'>) is not a valid source

Live streaming

Dear sir, I need to live streaming the video to YouTube using this library but I could not find the streaming class in this library. Please help to find out the solution

Error when attempting to connect.

I have tried a few of the examples on both a windows and mac machine and as soon as the script tries to connect I get an exception in Thread-4. I'm sure it is just me doing something dumb, any help would be appreciated. Thanks.

[Thu May 6 15:44:57 2021] Connecting to 192.168.199.240 Exception in thread Thread-4: Traceback (most recent call last): File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.1520.0_x64__qbz5n2kfra8p0\lib\threading.py", line 954, in _bootstrap_inner self.run() File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.1520.0_x64__qbz5n2kfra8p0\lib\threading.py", line 892, in run self._target(*self._args, **self._kwargs) File "C:\Users\Mark\Proshow Audiovisual\Engineering - Projects\Show Control\ATEM Controlers\PyATEMMax-master\examples\PyATEMMax\ATEMConnectionManager.py", line 306, in _commsThreadHandler while self._runLoop(): File "C:\Users\Mark\Proshow Audiovisual\Engineering - Projects\Show Control\ATEM Controlers\PyATEMMax-master\examples\PyATEMMax\ATEMConnectionManager.py", line 481, in _runLoop self._parsePacket(packetSize) # Parse EVERYTHING, don't trust packetLength !! File "C:\Users\Mark\Proshow Audiovisual\Engineering - Projects\Show Control\ATEM Controlers\PyATEMMax-master\examples\PyATEMMax\ATEMConnectionManager.py", line 714, in _parsePacket self._parseGetCommands(cmdStr) File "C:\Users\Mark\Proshow Audiovisual\Engineering - Projects\Show Control\ATEM Controlers\PyATEMMax-master\examples\PyATEMMax\ATEMConnectionManager.py", line 731, in _parseGetCommands self._cmdHandlers[cmdStr]["callback"](cmdStr) # Call method File "C:\Users\Mark\Proshow Audiovisual\Engineering - Projects\Show Control\ATEM Controlers\PyATEMMax-master\examples\PyATEMMax\ATEMCommandHandlers.py", line 92, in _mainHandler self._getHandler(cmdStr)() # Call specific handler File "C:\Users\Mark\Proshow Audiovisual\Engineering - Projects\Show Control\ATEM Controlers\PyATEMMax-master\examples\PyATEMMax\ATEMCommandHandlers.py", line 742, in _handleSSrc self._d.superSource.border.inner.width = self._inBuf.getFloat(16, False, 16, 100) File "C:\Users\Mark\Proshow Audiovisual\Engineering - Projects\Show Control\ATEM Controlers\PyATEMMax-master\examples\PyATEMMax\ATEMBuffer.py", line 198, in getFloat return self.getInt(offset, signed, bits) / factor File "C:\Users\Mark\Proshow Audiovisual\Engineering - Projects\Show Control\ATEM Controlers\PyATEMMax-master\examples\PyATEMMax\ATEMBuffer.py", line 149, in getInt return struct.unpack(self._getFormatChar(signed, bits), packedValue)[0] struct.error: unpack requires a buffer of 2 bytes [Thu May 6 15:44:58 2021] ERROR: no response from 192.168.199.240

execMacroStopRecording not working

Hi,

When using execMacroStopRecording, it throws the following error:

ubyte format requires 0 <= number <= 255

setMacroAction(macro_position, ATEMMacroActions.stopRecording) does work, however.

Bug: successive connect/disconnect crashes PyATEMMax

This simple script is enough to chrash the program:

import PyATEMMax
import time

switcher = PyATEMMax.ATEMMax()

switcher.connect("192.168.1.192")
testing = switcher.waitForConnection()
print ("connect 1", testing)
time.sleep(2)

testing = switcher.disconnect()
print ("disconnect 1", testing)
time.sleep(2)

switcher.connect("192.168.1.192")
testing = switcher.waitForConnection()
print ("connect 2", testing)
time.sleep(2)

testing = switcher.disconnect()
print ("disconnect 2", testing)
time.sleep(2)

By running the above script, here is the result:

C:\temp>python test.py
connect 1 True
disconnect 1 None
Exception in thread Thread-9 (_commsThreadHandler):
Traceback (most recent call last):
    File "C:\python31.164\Lib\threading.py", line 1038, in _bootstrap_inner
        self.run()
    File "C:\python31.164\Lib\threading.py", line 975, in run
        self._target(*self._args, **self._kwargs)
    File "C:\python31.164\Lib\site-packages\pyatemmax-1.0b9-py3.11.egg\PyATEMMax\ATEMConnectionManager.py", line 313, in _commsThreadHandler
    File "C:\python31.164\Lib\site-packages\pyatemmax-1.0b9-py3.11.egg\PyATEMMax\ATEMConnectionManager.py", line 408, in _runLoop
IndexError: list index out of range

Happens the same on Windows 10 and on Linux / Raspberry Pi OS and the same when connecting to a physical ATEM 1 M/E Constellation HD and to the virtual pyAtemSim simulator.

??

(the goal here is to use this kind of sequence within a wxPython program that has explicit Connect / Disconnect buttons)

Detect when the PVW/PGM has changed

Is it possible to see if the PVW or the PGM has changed? Maybe when the PVW has changed from another software (e.g. someone using the Atem Software Control), then my program detects it, and print that which camera is on PVW?

Cannot Access Data

I'm on a Macbook Pro MacOS 10.15.7. I can connect to an ATEM Mini Pro and I can send Set and Exec commands to it successfully but I cannot access any data from the device. All the parameters show either 0 or blank.
Edit: Cancel this query - it was my own stupid fault.

ISO Recording implementation

Would be possible to implement a functionality to start and stop ISO recording? I'm using the newer Atem Minis.
If not, is there another method to get the same results?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.