I am new to Microsoft Smooth Streaming and have questions about the making of composite manifests.
Following the guidance from here.
I was able to make a composite manifest of a single clip element that played in Silverlight player.
However, when I try to add more clips from other videos, the player stopped working and gave out no error information.
And I am doing this all by hand. and when I trying to use the Expression Encoder 4 Pro to create such a video, I got a normal .ismc
file instead of a .csm
file.
My questions are:
What is the best way of making a composite manifest which contains clips from different videos? Is there any spec to follow when encoding these videos? or does the support of composite manifest put any restriction on the video format?
And the last one is: Is there an easy way to debug it (like validating my .csm file)?
EDIT my own solution:
Looks like no one cares about this, but since I finally solved this, I am writing this down here to save others' time.
to debug a composite manifest, I built a simple Silverlight app in Visual Studio, and add a simple function to report an error:
MainPage.xaml.cs:
public MainPage()
{
InitializeComponent();
this.SmoothPlayer.SmoothStreamingErrorOccurred += new EventHandler<SmoothStreamingErrorEventArgs>(SmoothPlayer_SmoothStreamingErrorOccurred);
}
public void SmoothPlayer_SmoothStreamingErrorOccurred(object sender,
SmoothStreamingErrorEventArgs e)
{
MessageBox.Show("Error: " + e.ErrorCode + "; " + e.ErrorMessage);
}
And I found this web page useful.
You need to use:
<c t="", d"">
instead of
<c d="">
You have to calculate the ClipBegin
and ClipEnd
values right.
Below is a sample code in python to convert a .ismc
to a .csm
(assume that the ism below is an xml.etree.ElementTree object representation of the manifest xml content):
def ism2csm(url, ism):
if ism is None: return csm
csm = xml.Element('SmoothStreamingMedia', {'MajorVersion':'2', 'MinorVersion':'1', 'Duration':ism.attrib.get('Duration')})
clip = xml.Element('Clip', {'Url':url, 'ClipBegin':'0','ClipEnd':'0'})
csm.append(clip)
for stream_index in ism.iter('StreamIndex'):
clip.append(stream_index)
for stream_index in clip.iter('StreamIndex'):
t = 0
last_c = None
for c in stream_index.iter('c'):
c.attrib['t'] = str(t)
t += int(c.attrib.get('d'))
if last_c is not None: del last_c.attrib['d']
last_c = c
if clip.attrib.get('ClipEnd') == '0':
clip.attrib['ClipEnd'] = str(t)
return csm