I’m making a small tool that’s gonna extract the closest image related to a alarm starttime, save the image and then exit. I’m having the event server serialize all cameras to a text file, then opening the application to save the images. This is my code:
static void Main(string[] args)
{
if (args.Length < 1)
return;
//VideoOS.Platform.SDK.Environment.Initialize();
VideoOS.Platform.SDK.Export.Environment.Initialize();
VideoOS.Platform.SDK.Environment.AddServer(new Uri("http://localhost"), CredentialCache.DefaultNetworkCredentials);
var items = new List<Item>();
foreach (string line in File.ReadAllLines(args[1])) // path to textfile
{
items.Add(Item.Deserialize(line));
}
var myFolder = Path.GetDirectoryName(args[1]);
//var item = Item.Deserialize(args[0]);
for (int i = 0; i < items.Count; i++)
{
Image.FromStream(GetImage(items[i], DateTime.Parse(args[0]))).Save(Path.Combine(myFolder, "tmpImage" + i + ".jpeg"));
}
}
static MemoryStream GetImage(Item camera, DateTime alarmDate)
{
JPEGVideoSource videoSource = new JPEGVideoSource(camera);
videoSource.AllowUpscaling = true;
videoSource.Init();
JPEGData data = videoSource.GetNearest(alarmDate) as JPEGData;
MemoryStream ms = new MemoryStream(data.Bytes);
ms.Position = 0;
return ms;
}
Also getting this with config “Any CPU”. The error I got above was with only x64. x86 doesn’t run.
There was a mismatch between the processor architecture of the project being built “MSIL” and the processor architecture of the reference “VideoOS.Platform.SDK.Export, Version=4.0.0.0, Culture=neutral, PublicKeyToken=bc60fba4a7969f89, processorArchitecture=AMD64”, “AMD64”. This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project.
Path to DLL: [C:\Program](file:C:/Program) Files\Milestone\MIPSDK\Bin\VideoOS.Platform.SDK.Export.dll
I have CopyExportFiles.bat as post-build event to the output folder.
It seems to me the shipped VideoOS.Platform.SDK.Export.dll is 32 bit…
You must start with
VideoOS.Platform.SDK.Environment.Initialize();
if you have it commented out it would not work.
Try as an experiment to include also
VideoOS.Platform.SDK.Media.Environment.Initialize();
If the issue is not solved..
What is your MIP SDK?
Do you or did you use a 32 bit version of the MIP SDK?
I’ve tried with that on aswell.
Latest MIP version. No 32 bit, just the default install.
Same error on .Media
System.IO.FileNotFoundException: Det går inte att läsa in filen eller sammansättningen VideoOS.Toolkit.dll eller ett av dess beroenden. Det går inte att hitta den angivna modulen.
Filnamn: VideoOS.Toolkit.dll
vid VideoOS.Platform.SDK.Media.SDKInternalMediaService..ctor()
vid VideoOS.Platform.SDK.Media.Environment.Initialize()
vid GetAlarmImage.Program.Main(String[] args) i E:\Dropbox\Dev\TryggLarm\GetAlarmImage\Program.cs:rad 40
Make sure you build x64 (anyCpu will not work).
I believe the CameraStreamResolution does much the same, does that sample work for you? (Note there is a Post-build event command line in the sample)
Using x64 makes no difference for me. Actually, that sample has AnyCpu when I open it. I have that post build event also.
That sample doesn’t seem to have line
VideoOS.Platform.SDK.Export.Environment.Initialize();
but it works either way.. When I skip that line, I get this error on videoSource.Init();
VideoOS.Platform.MIPException: Missing library: VideoOS.Platform.SDK.Export.dll
vid VideoOS.Platform.Util.InternalCommandService.TryLoad()
vid VideoOS.Platform.Util.InternalCommandService.ImageExporterConnect(FQID deviceFQID, Int32 width, Int32 height)
vid VideoOS.Platform.Data.JPEGVideoSource.Init(Int32 width, Int32 height)
vid GetAlarmImage.Program.GetImage(Item camera, DateTime alarmDate) i E:\Dropbox\Dev\TryggLarm\GetAlarmImage\Program.cs:rad 66
vid GetAlarmImage.Program.Main(String[] args) i E:\Dropbox\Dev\TryggLarm\GetAlarmImage\Program.cs:rad 53
Also worth noting that the required files is in the same folder as the .exe.
The screen captures show a lot of files is missing.
Try to compare with the folder for the CameraStreamResolution sample that works for you.
Yes but I only want to use the .Export files. I can try with all those files and let you know the result.
Amazingly, it now works while debugging in Visual Studio. But it gives the same error when started from the Event Server.. Can it be that those files need to be located in the Event server .exe aswell?
I am well aware of this and that’s why I use a external application to just save the image (hence GetAlarmImage.exe)
If you want to try to replicate my problem:
Make a background plugin running on the Event server. Subscribe to new alarm messages. On a new alarm, serialize the related cameras and save it to a file. Open a external application that reads the file and deserializes the items, then getting a image from the camera via JPEGVideoSource, and then exits the application.
I’m currently stuck in development, really need to solve this issue.
This my function getting images from a alarms related cameras in the EVENT server:
List<MemoryStream> CreateImages(Alarm alarm)
{
var msList = new List<MemoryStream>();
EnvironmentManager.Instance.Log(false, "TryggLarm", "Searching for images..", null);
string appData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
string myFolder = Path.Combine(appData, "TryggLarm.GetAlarmImage");
Directory.CreateDirectory(myFolder);
var lines = new List<string>();
foreach(var cam in alarm.ReferenceList)
{
lines.Add(Configuration.Instance.GetItem(cam.FQID).Serialize());
}
var p = Path.Combine(myFolder, "refCams.txt");
File.WriteAllLines(p, lines.ToArray());
var procStartInfo = new ProcessStartInfo(@"C:\Program Files\Milestone\MIPPlugins\TryggLarm\GetAlarmImage.exe", "\"" + alarm.EventHeader.Timestamp.ToString() +"\"" + " " + p);
//procStartInfo.UseShellExecute = false;
var proc = Process.Start(procStartInfo);
proc.WaitForExit(10 * 1000);
var imgFiles = Directory.GetFiles(myFolder, "*.jpeg");
foreach(var file in imgFiles)
{
var ms = new MemoryStream(File.ReadAllBytes(file));
ms.Position = 0;
msList.Add(ms);
}
return msList;
}
The application GetAlarmImage.exe will inherit the Event servers rights and runas user so ..
string appData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
ownFolder = Path.Combine(appData, "TryggLarm.GetAlarmImage");
Directory.CreateDirectory(ownFolder);
.. will return the same folder as the event servers appdata folder ([C:\Windows\ServiceProfiles\NetworkService\AppData\Local)](file:C:/Windows/ServiceProfiles/NetworkService/AppData/Local)) so it can successfully write and edit files stored in it’s own folder.
I consulted a more experienced developer colleague. We have a good guess based on experience. When you launch the app, if current directory is not the folder where the executable is located, then the dependent files will not be found.