using System; using System.Threading; using Interop.TimecodeLib; 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) { // this example shows how to do insert edits and dual-context transitions. It uses three 10 second clips // in the V:\default bin called "test1", "test2", and "test3". 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 = ""; 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 ) { ////////////////////////// // DO WORK HERE ////////////////////////// // for AppServerMgr functions call: connection.AppServerMgr.Function() // for AppServer functions call: connection.AppServer.Function() const int INT_MIN = -2147483648; const int INT_MAX = 2147483647; string channel = "C2"; // create a controller bool isNewController = false; ISimpleController controller = connection.AppServer.CreateController( appName, channel, out isNewController); ISimplePlayerRecorder player = (ISimplePlayerRecorder) controller; ITwoHeadPlayerRecorder preview = (ITwoHeadPlayerRecorder) controller; // create a media mgr and make sure that temporary scratch clip does not exist IMediaMgr mediaMgr = connection.AppServer.CreateMediaMgr(appName); string scratchClip = "edl/cmf//local/V:/default/~myscratchclip"; if ( mediaMgr.AssetExists( scratchClip ) ) mediaMgr.DeleteAsset(scratchClip); // create a new scratch clip player.SetCurrentBin("V:", "default"); player.New("~myscratchclip"); ISimpleEditor editor = (ISimpleEditor) player.GetEditor(); //insert clip 2 at the end of the scratch clip -- passing in empty string edit ID does this. returns an ID string of the edit. string editID2 = editor.InsertEdit("edl/cmf//local/V:/default/test2", "", INT_MIN, INT_MAX, 0); // insert clip 1 before clip 2 above string editID1 = editor.InsertEdit("edl/cmf//local/V:/default/test1", editID2, INT_MIN, INT_MAX, 0); // cue it up and start playing, this wil play clip 1, then clip 2 player.CueStart(); player.Play(); // while main context is playing, load preview context with 3rd clip preview.LoadPreview("edl/cmf//local/V:/default/test3"); // EXAMPLE 1: preview context starts playing after main context ends preview.BeginPreviewContextChange(); preview.CueStart(); // cue to some position preview.Play(); // tell preview context to go active after primary context finishes preview.CommitContextChange("follow"); // manual or follow Thread.Sleep(35000); /* // EXAMPLE 2: start & end limits - timeline relative, not clip player.SetStartLimit("00:00:05,00"); player.SetEndLimit("00:00:10,00"); Thread.Sleep(20000); */ /* // EXAMPLE 3: force change to second context // Sleep 15 seconds Thread.Sleep(5000); // then force an immediate context change i.e. asap preview.BeginPreviewContextChange(); preview.Play(); preview.CommitContextChange("asap"); // sleep awhile to see the result on the output Thread.Sleep(15000); */ /* // EXAMPLE 4: second context is *scheduled* to play 5 seconds after start string timeOfDay = (string) player.GetStatus("timeofdaystr"); string videoFormat = (string) player.GetStatus("videoformatstr"); // create a new timecode object & set its video format VdrTimecode timecode = new VdrTimecode(); timecode.VideoFormat = videoFormat; // set the value equal to current position + 5 seconds timecode.AsString = timeOfDay; timecode.Add("00:00:05,00"); // clip must be queued before scheduling a context change using time of day preview.BeginPreviewContextChange(); preview.CueStart(); // manually commit the CueStart context change. A manual operation performs // the operation but does not perform the context change. So the preview // clip cues to start, but the preview context does not become active preview.CommitContextChange("manual"); // schedule the play command to time of day preview.BeginPreviewContextChange(); preview.Play(); preview.ScheduleContextChange("timeofday", timecode.AsString); //player.CancelScheduledChange ("timeofday", timecode.AsString); */ // eject the clip player.Stop(); player.Eject(); // close the channel controller.CloseChannel(); // delete scratch clip if ( mediaMgr.AssetExists( scratchClip ) ) mediaMgr.DeleteAsset(scratchClip); } } } 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(); } } }