Updating multimedia component using TOM.NET - components

I am trying to update the metadata on the multimedia image in C# using Tridion's TOM.NET API like this
componentMM.LoadXML(localComponent.GetXML(XMLReadFilter.XMLReadALL));
// make changes to the component mm multimedia text;
localComponent.UpdateXML(componentMM.InnerXML);
localComponent.Save(True)
While this works for other components, it is failing for Multimedia images.
<?xml version="1.0"?>
<tcm:Error xmlns:tcm="http://www.tridion.com/ContentManager/5.0"
ErrorCode="80040345" Category="19" Source="Kernel" Severity="2">
<tcm:Line ErrorCode="80040345" Cause="false" MessageID="16137"><![CDATA[
Unable to save Component (tcm:33-32599).
]]><tcm:Token>RESID_4574</tcm:Token>
<tcm:Token>RESID_4418</tcm:Token>
<tcm:Token>tcm:33-32599</tcm:Token>
</tcm:Line>
<tcm:Line ErrorCode="80040345" Cause="true" MessageID="15747"><![CDATA[
Unexpected element: MultimediaFileSize
]]><tcm:Token>MultimediaFileSize</tcm:Token>
</tcm:Line>
<tcm:Details>
<tcm:CallStack>
<tcm:Location>ComponentBL.CheckMultiMediaProperties</tcm:Location>
<tcm:Location>ComponentBL.CheckMultiMediaProperties</tcm:Location>
<tcm:Location>ComponentBL.Update</tcm:Location>
<tcm:Location>XMLState.Save</tcm:Location>
<tcm:Location>Component.Save</tcm:Location>
</tcm:CallStack>
</tcm:Details>
</tcm:Error>
Can you please let me know what am I doing wrong here?

Thanks for your responses. I was deleting the node but at the wrong place. I update the code like this and it works fine now.
if (localComponent.IsMultimediaComponent)
{
XmlNode multimediaFileSizeNode = localComponentXML.SelectSingleNode("//*[local-name()='MultimediaFileSize']",tridionNamespace);
XmlNode dataNode = multimediaFileSizeNode.ParentNode;
dataNode.RemoveChild(multimediaFileSizeNode);
}
localComponent.UpdateXML(localComponentXML.InnerXml);

Include only the tcm:Metadata node in your update?
Specifically, it is complaining about you specifying the size of the mm file, which you shouldn't, that's a system property. Clean up the XML you receive from Tridion to remove that property (it might then complain about another property, just do what it asks you to).
EDIT: Reading the error messages is a great skill to have...

When you do this you need to only save the modified metadata data (not the entire XML). Try removing all of the child nodes except tcm:Metadata from the XML structure before calling .UpdateXML()
Perhaps you could paste your sample XML if you need further assistance.

I usually do this way:-
mComponent = (Component)mTDSE.GetObject("YOUR-COMPONENT-ID", EnumOpenMode.OpenModeView, null, XMLReadFilter.XMLReadAll);
mComponent.CheckOut(false);
mComponent.MetadataFields["YOUR-METADATA-FIELD-NAME"].value[1] = "VALUE TO BE REPLACED";
mComponent.Save(true);

Related

Method to clear pre-filled data of a ST.future.Component

Is there a way to clear an input field while using the ST.component("locator"); API?
Using ST.component("locator").setValue(""); results in the following error:
TypeError: ST.component(...).setValue is not a function...
PS: Is the old forum now permanently closed? Is there a way to view older questions?
Edit: Seems like the other forum was down yesterday, therefore the PS.
If it's an Ext JS field you will need to use the ST.field API in Sencha Test, which has a setValue method. This method isn't available on the more generic ST.component API.
ST.field('myfield')
.setValue('');
Or if it's a normal input field (not an Ext JS component), then you can do the following:
ST.element('#myfield')
.execute(function(field) {
field.dom.value = '';
});

How to read an SVG file from stream with MagickNet

My application allows the user to upload images and send them to the service, which then converts it to another format and sends it back. We are adding support for the SVG file format and I am running into an issue with reading the file from a byte array.
The issue is that when I initialize a MagickImageInfo object with the SVG Stream object, I get this error:
"no decode delegate for this image format '' # error/blob.c/BlobToImage/355"
I played around with it and am able to get past this error if I instead create a MagickImage object and supply it with an instance of MagickReadSettings where I set the Format to SVG explicitly.
The core problem is that the MagickImage code needs a hint as to what kind of file it is when it's an SVG. For other file types, it seems to be able to infer what kind of file it is. However, while I am able to supply the MagickImage class with what format the file is, the MagickImageInfo class doesn't have any parameters that I can give it to hint at the file type.
One possible solution would be to write the file to disk, then have MagickImageInfo class read the file from disk, but I really don't want to do this as it adds complexity to the service and makes it depend on disk write access.
Relevant code:
Working code:
var readSettings = new MagickReadSettings() { Format = MagickFormat.Svg };
using (MagickImage image = new MagickImage(stream, readSettings))
{
image.Write("C:\test"); // Actual code doesn't write to disk
}
Not working code:
MagickImageInfo info = new MagickImageInfo(stream);
It appears that you found a missing feature. I found your post here and added an extra overload for the MagickImageInfo constructor. The following will be available in Magick.NET 7.0.3.9 and higher:
var readSettings = new MagickReadSettings() { Format = MagickFormat.Svg };
MagickImageInfo info = new MagickImageInfo(stream, readSettings);
Feel free to open an issue next time here: https://github.com/dlemstra/Magick.NET or here: https://magick.codeplex.com/discussions

Adjusting AVAudioMix volume property has no effect in iOS9

I have an app which loads local files into an avPlayer via a AVMutableComposition, it may have as many as 6 audio and video tracks as part of the composition.
I have a UISlider which is used to adjust the volume of each track in the player.
Below is the code used to update the volume.
- (void)updateVolumeForTake:(Take *)take
{
NSInteger trackID = // method that gets trackID
AVMutableAudioMix *audioMix = self.player.currentItem.audioMix.mutableCopy;
NSMutableArray *inputParameters = audioMix.inputParameters.mutableCopy;
AVMutableAudioMixInputParameters *audioInputParams = [inputParameters filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:kTrackIdPredicate, trackID]].firstObject;
[audioInputParams setVolume:myNewVolumeFloat atTime:myDesiredTime];
audioMix.inputParameters = inputParameters;
AVPlayerItem *playerItem = self.player.currentItem;
playerItem.audioMix = audioMix;
}
This is is currently live in the appStore and has been since iOS6 and has always worked with no issue.
On a device running iOS9, the above no longer works at all. I have looked at the release notes and although there is some mention of AVFoundation, I didn't see anything regarding AVAudioMix.I have googled around and have not found anyone else with this issue.
I also tried creating a new project with nothing but an AVPlayer and UISlider and I saw the same behaviour.
My question is as follows, has anyone else experienced this issue?
Is anyone aware of a known bug related to this?
I have found a solution but unfortunately not an exact cause.
I can't say I fully understand why this fixed my issue but here is the solution and an attempt at explaining why it fixed the issue I was experiencing.
- (void)updateVolumeForTake:(Take *)take
{
AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
NSMutableArray *inputParameters = [self.inputParameters filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:kNotTrackIdPredicate, myTrackID]].mutableCopy;
AVCompositionTrack *track = (AVCompositionTrack *)[self.composition trackWithTrackID:myTrackID];
AVMutableAudioMixInputParameters *audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:track];
[audioInputParams setVolume:myDesiredVolume atTime:kCMTimeZero];
[inputParameters addObject:audioInputParams];
audioMix.inputParameters = inputParameters;
AVPlayerItem *playerItem = self.player.currentItem;
playerItem.audioMix = audioMix;
self.inputParameters = inputParameters;
}
As you can see above, I have stopped using mutable copies of my AVAudioMix and its inputParameters and instead created a new AVAudioMix and NSMutableArray for inputParameters. The new inputParameters array is a copy of the existing inputParameters (referenced from a property 'self.inputParameters') minus the track matching the one I wish to change.
Secondly I create a new instance of AVMutableAudioMixInputParameters using the track with which I wish to edit the volume of (previously I was getting reference to the existing params with matching trackID and modifying them). I edit that add it to my new array and make that the audio mix of currentItem.
Again I can't say with any certainty why this fixes it, but it did for me, I wonder if all the mutable copies were not being discovered as different at all when I reassigned the audioMix of the playerItem and thats why I didn't hear any change in the volume. (although this seems doubtful).
Anyway my issue is fixed and I hope this can help anyone who has a similar issue.

Nodejs: parsing XML, editing values, saving the end result using sax-js module

What I'd like to achieve is:
parsing a chunk of XML
editing some values
saving the end result in a
new xml file
The module is sax-js: https://github.com/isaacs/sax-js#readme
The module has some built-in mechanism to read/write any.
I thought the task would be a piece of cake; on the contrary I have been struggling with it for the whole day.
Here is my code:
var fs = require('fs');
var saxStream = require("sax").createStream(true);
saxStream.on("text", function (node) {
if (node === 'foo') { //the content I want to update
node = 'blabla';
}
});
fs.createReadStream("mysongs.xml")
.pipe(saxStream)
.pipe(fs.createWriteStream("mysongs-copy.xml"));
I did think that updating some content (see the comment above) would suffice to write the updated stream into a new file.
What's wrong with this code?
Thanks for your help,
Roland
The sax module doesn't let you modify nodes like that. If you take a look at this bit of code, you'll see that the input is passed indiscriminately to the output.
All hope is not, however, lost! Check out the pretty-print example - it would be a good starting point for what you want to do. You'd have to do a bit of work to implement the readable part of the stream, though, if you still want to be able to .pipe() out of it.
If you know the general structure of the XML, you can try xml-flow. It converts an XML stream into objects, but has a utility to convert them back to xml strings:
https://github.com/matthewmatician/xml-flow
Based on deoxxa's answer I wrote an NPM module for this https://www.npmjs.com/package/sax-streamer

raphael text() not working in ie9

Why is the following example not working in ie9?
http://jsfiddle.net/dzyyd/2/
It spits out a console error:
"Unexpected call to method or property access."
I found it pretty quickly. You created the element, but did not put it anywhere. Once it is added to the document body, everything seems to be fine.
this._width=300;
this._height=300;
this._bgSvgContainer = document.createElement("div");
//NOTE: add the created div to the body of the document so that it is displayed
document.body.appendChild(this._bgSvgContainer);
var bgCanvas = Raphael(this._bgSvgContainer, this._width, this._height);
this._bgCanvas = bgCanvas;
var num = this._bgCanvas.text(this._width-10,this._height-10,"1");
It's really hard to tell with such a tiny code-fragment (doesn't run on any browser for me), but it's probably a scope issue this in IE during events is completely different to this using the W3C event model. See: quirksmode-Event order-Problems of the Microsoft model

Resources