- Posts: 29
- Joined: Thu Apr 21, 2016 3:28 pm
Been trying to create an app to control a Hyperdeck Studio through a ATEM 2/ME Production studio 4K. As I undestand, I should be able to do this with the HyperdeckIterator Interface. I've looked at the example C# app that came with the SDK and manged to get a procedure that compiles cleanly but when the procedure is called I get the following error:
I'm not sure how to fix this as the code does not throw any warnings. The error is thrown at the line " m_switcher.CreateIterator(ref HyperDeckIteratorInterfaceID, out HyperDeckIteratorPointer);"
Here's the code:
- Code: Select all
System.InvalidCastException was unhandled
HResult=-2147467262
Message=Unable to cast COM object of type 'System.__ComObject' to interface type 'BMDSwitcherAPI.IBMDSwitcher'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{3D480E2F-3CF4-474B-92E7-B7907EE83B41}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
Source=mscorlib
StackTrace:
at System.StubHelpers.StubHelpers.GetCOMIPFromRCW(Object objSrc, IntPtr pCPCMD, IntPtr& ppTarget, Boolean& pfNeedsRelease)
at BMDSwitcherAPI.IBMDSwitcher.CreateIterator(Guid& iid, IntPtr& ppv)
at CasparCGClientForm.WMES.HyperDeckRec() in D:\CasparCG Client\CasparCGClientForm\CasparCGClientForm\Form1.cs:line 81
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
I'm not sure how to fix this as the code does not throw any warnings. The error is thrown at the line " m_switcher.CreateIterator(ref HyperDeckIteratorInterfaceID, out HyperDeckIteratorPointer);"
Here's the code:
- Code: Select all
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using CasparCGNETConnector;
using System.Runtime.InteropServices;
using BMDSwitcherAPI;
using System.Data.OleDb;
using System.Media;
namespace CasparCGClientForm
{
public partial class WMES : Form
{
private SoundPlayer _soundplayer;
//Create a Caspar server connection variable
private ICasparCGConnection con;
//Start the ATEM Switcher connection variables
private IBMDSwitcherDiscovery m_switcherDiscovery;
private IBMDSwitcher m_switcher;
private IBMDSwitcherHyperDeck switcherHyperdeck;
// create variable to check for lower third on or off and server connection
Boolean servers_OK = false;
public WMES()
{
InitializeComponent();
}
private void devices_connect_Click(object sender, EventArgs e)
{
//Connect to CG Server & ATEM Switcher
if (Connect_caspar() & Connect_atem())
{
servers_OK = true;
devices_Connect.Text = "Connected!";
checkmark_symbol.Visible = true;
}
else
{
servers_OK = false;
checkmark_symbol.Visible = false;
}
}
public Boolean Connect_atem()
{
_BMDSwitcherConnectToFailure failReason = 0;
string address = switchertextBox.Text;
Boolean atem_connection;
try
{
// Connect to switcher. Do this in a separate thread to prevent the main GUI thread blocking.
m_switcherDiscovery = new CBMDSwitcherDiscovery();
if (m_switcherDiscovery == null)
{
MessageBox.Show("Could not create Switcher Discovery Instance.\nATEM Switcher Software may not be installed.", "Error");
Environment.Exit(1);
}
m_switcherDiscovery.ConnectTo(address, out m_switcher, out failReason);
//Use threading
new Thread(() =>
{
}).Start();
atem_connection = true;
return atem_connection;
//SwitcherConnected();
}
catch (COMException)
{
// An exception will be thrown if ConnectTo fails.
switch (failReason)
{
case _BMDSwitcherConnectToFailure.bmdSwitcherConnectToFailureNoResponse:
MessageBox.Show("No response from Switcher", "Error");
break;
case _BMDSwitcherConnectToFailure.bmdSwitcherConnectToFailureIncompatibleFirmware:
MessageBox.Show("Switcher has incompatible firmware", "Error");
break;
default:
MessageBox.Show("Connection failed for unknown reason", "Error");
break;
}
atem_connection = false;
return atem_connection;
}
}
private void button32_Click(object sender, EventArgs e)
{
_soundplayer = new SoundPlayer("click_spacey.wav");
_soundplayer.Play();
if (recordbtnpressed == false)
{
recordbtnpressed = true;
}else { recordbtnpressed = false; }
if (recordbtnpressed == true)
{
VideoRecording = true;
button32.BackColor = Color.Red;
timer1.Start();
Thread t = new Thread(HyperDeckRec);
t.SetApartmentState(ApartmentState.MTA);
t.Start();
//HyperDeckRec();
//RunMacro(25);
timer2.Start();
button29.Enabled = false;
button23.Enabled = false;
button30.Enabled = false;
button27.Enabled = false;
}
else
{
timer1.Stop();
timer2.Stop();
RunMacro(31);
button32.Visible = true;
button32.BackColor = Color.DimGray;
button32.Text = "REC";
button29.Enabled = true;
button23.Enabled = true;
button30.Enabled = true;
button27.Enabled = true;
}
}
public void HyperDeckRec()
{
IBMDSwitcherHyperDeckIterator m_HyperDeckIterator = null;
IntPtr HyperDeckIteratorPointer;
Guid HyperDeckIteratorInterfaceID = typeof(IBMDSwitcherHyperDeckIterator).GUID;
m_switcher.CreateIterator(ref HyperDeckIteratorInterfaceID, out HyperDeckIteratorPointer);
if (HyperDeckIteratorPointer == null)
return;
m_HyperDeckIterator = (IBMDSwitcherHyperDeckIterator)Marshal.GetObjectForIUnknown(HyperDeckIteratorPointer);
if (m_HyperDeckIterator == null)
return;
IBMDSwitcherHyperDeck switcherHyperdeck;
m_HyperDeckIterator.Next(out switcherHyperdeck);
switcherHyperdeck.Record();
}
}