using System;
using System.IO;
using GrassValley.Mseries.AppServer;
using GrassValley.Mseries.AppServerLog;
using GrassValley.Mseries.ChanStatus;
using GrassValley.Mseries.ConfigMgr;
using GrassValley.Mseries.Control;
using GrassValley.Mseries.DVCapture;
using GrassValley.Mseries.Editor;
using GrassValley.Mseries.MediaMgr;
using GrassValley.Mseries.Security;
using GrassValley.Mseries.Status;
using GrassValley.Mseries.TransferQueue;
// Leave the following "css_reference" lines in when running with CS-Script. They're
// more than just comments - they tell CS-Script which DLLs to load if the DLL
// name does not match the namespace that it implements.
//css_reference Credentials.dll;
//css_reference ServerUtil.dll;
///
/// This is a sample CS-Script app for controlling the Grass Valley K2 server.
/// The code is regular C# code, but it's written for CS-Script which can
/// run it as a script from a DOS command prompt.
///
/// Go to the K2 AppServer Developer's Guide for more information:
/// http://www.gvgdevelopers.com/K2DevGuide/K2DevGuide.html#%5B%5BCS-Script%20Sample%20Scripts%5D%5D
///
/// For more information about CS-Script go to:
/// http://www.members.optusnet.com.au/~olegshilo/
///
namespace K2Script
{
class Test
{
static int Main(string[] args)
{
try
{
// get the application's name & create a unique suite name
string appName = Environment.GetCommandLineArgs()[0];
string suiteName = appName + "_" + System.Guid.NewGuid().ToString("N");
// fill in these values for your connection (i.e. hardcode them, pass in cmdline arguments, read from file, read from console, etc.)
string host = "localhost";
string username = "";
string password = "";
string domain = "";
// Connect to host & pass in credentials. The "using" block disposes connection when done.
using ( Connection connection = new Connection(appName, suiteName,
host, username, password, domain) )
{
// do work only if we have a valid connection
if ( connection.IsConnected )
{
// create a media mgr
using ( IMediaMgr mediaMgr = connection.AppServer.CreateMediaMgr(appName) )
{
// define clip to modify
string volume = "V:";
string bin = "default";
string clipname = "Clip";
string dataFile = "C:\\temp\\anc_data.N0";
string clipURI = String.Format("edl/cmf//{0}/{1}/{2}/{3}", host, volume, bin, clipname);
// get an editor for clip
using ( ISimpleEditor editor = (ISimpleEditor) mediaMgr.CreateEditor(clipURI) )
{
try
{
// cast it to a track editor
ITrackEditor2 trackEditor = (ITrackEditor2) editor;
/////////////////////////////////////////////////////
// Example 1: Merge the ENTIRE datafile into the clip
/////////////////////////////////////////////////////
// srcFieldIn = -1 == start of file
// srcFieldOut = -1 == end of file,
// destFieldPos = 0 == field 0 in destination. note: you can use a timecode string too (i.e. "00:00:00.00")
// merge = 1 == merge, rather than replace
string ancFileName = trackEditor.MergeAncData (dataFile, -1, -1, 0, 1);
// commit the change
trackEditor.CommitAncData();
/*
//////////////////////////////////////////////////////////////////
// Example 2: Merge PART of the datafile (first 300 fields) into the clip
//////////////////////////////////////////////////////////////////
// srcFieldIn = 0 == field 0
// srcFieldOut = 300 == up to field 300
// destFieldPos = 0 == field 0 in destination. note: you can use a timecode string too (i.e. "00:00:00.00")
// merge = 1 == merge, rather than replace
string ancFileName = trackEditor.MergeAncData (dataFile, 0, 300, 0, 1);
// commit the change
trackEditor.CommitAncData();
*/
/*
//////////////////////////////////////////////////////////////////
// Example 3: Replace or Add the clip's ancillary data track
//////////////////////////////////////////////////////////////////
// srcFieldIn = -1 == start of file
// srcFieldOut = -1 == end of file,
// destFieldPos = 0 == field 0 in destination. note: you can use a timecode string too (i.e. "00:00:00.00")
// merge = 0 == replace, rather than merge
// Note: if replacing or adding (i.e. the original clip does not have an ancillary data track) rather than
// merging then you first need to copy the local data file over to the K2 Client's V: drive. To do this, you
// should copy the local file to a location and name on the K2 Client's V: drive that looks like
// "V:\PDR\\\.N0". Then you can use that file with the TrackEditor's MergeAncData
// call to replace the ancillary data track.
// first generate unique guid name & path
string newDataFile = String.Format("V:\\PDR\\{0}\\{1}.N0", bin, System.Guid.NewGuid().ToString("N"));
// if the newDataFile does not exists
if ( File.Exists(newDataFile) )
{
Console.WriteLine("ERROR: Cannot copy '{0}' to '{1}'. File '{1}' already exists.", dataFile, newDataFile);
return -1;
}
// copy local data file to V: drive
File.Copy( dataFile, newDataFile );
// replace the clip's anc data track
trackEditor.MergeAncData (newDataFile, -1, -1, 0, 0);
// commit the change
trackEditor.CommitAncData();
string ancFileName = newDataFile;
*/
// output new ancillary file info
Console.WriteLine("The new ancillary filename is located at '{0}'", ancFileName);
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
// Very Important: make sure that you detach the editor when you're done. If not, you will
// have references to the movie hanging around. This will cause you trouble later when you
// try to delete or move the clip, but can't because of outstanding references to the clip.
editor.Detach();
}
} // when using block goes out of scope the simpleeditor is disposed
} // when using block goes out of scope the mediamgr is disposed
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
return 0;
}
}
// Connection helper class: sets up credentials & hostname, connects to K2
public class Connection: IDisposable
{
private bool _connected = false;
private AppServerMgrProxy _appServerMgrProxy = null;
private IAppServer _appServer = null;
///
/// Object that connects to the specified K2 credentials
///
/// The application's name.
/// The suite's name.
/// The K2's host name.
/// The username.
/// The password.
/// The domain.
public Connection(string appname, string suitename, string host, string username, string password, string domain)
{
try
{
//////////////////////////
// SETUP
//////////////////////////
if ( null == host || host.Length == 0)
{
Console.WriteLine("Empty host name passed to Connection object.");
return;
}
//////////////////////////
// CONNECT TO K2
//////////////////////////
// create an AppServerMgr proxy object
_appServerMgrProxy = new AppServerMgrProxy();
// tell it which K2 we're connecting to
_appServerMgrProxy.SetHost(host);
// give it the user credentials we want to use
if ( username.Length > 0 )
_appServerMgrProxy.SetUserCredentials(username, password, domain, false);
// connect to the K2's AppServerMgr
if ( !_appServerMgrProxy.Connect() )
{
// if the connection failed, report an error and exit
Console.WriteLine("ERROR: Could not connect to AppService on host '" + host + "'. Check the host name.");
_appServerMgrProxy = null;
return;
}
// if we got here we're connected to K2 AppService
//////////////////////////
// CREATE AN APPSERVER
//////////////////////////
// now create an AppServer
bool newConnection = false;
_appServer = _appServerMgrProxy.CreateAppServer(suitename,
appname, out newConnection);
_connected = true;
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
///
/// Gets a value indicating whether this instance is connected.
///
///
/// true if this instance is connected; otherwise, false.
///
public bool IsConnected
{
get
{
return _connected;
}
}
///
/// Gets the AppServerMgr.
///
/// The AppServerMgr
public AppServerMgrProxy AppServerMgr
{
get
{
if ( _appServerMgrProxy == null )
Console.WriteLine("WARNING: AppServerMgrProxy object == null!");
return _appServerMgrProxy;
}
}
///
/// Gets the AppServer
///
/// The AppServer
public IAppServer AppServer
{
get
{
if ( _appServerMgrProxy == null )
Console.WriteLine("WARNING: AppServerProxy object == null!");
return _appServer;
}
}
///
/// Disposes this instance.
///
public void Dispose()
{
if ( _appServer != null )
_appServer.CloseConnection();
}
}
}