qoollo / SharpDashTools

MPEG-DASH tools in C#
MIT License
24 stars 7 forks source link

Problem with xml validation #2

Open jakoss opened 7 years ago

jakoss commented 7 years ago

Hi

I'm trying to save 30 seconds of live stream to file, but i keep getting exceptions on bad XML schema. With code:

private static async Task MainAsync()
        {
            var url = "http://ncplusgo.s43-po.live.e56-po.insyscd.net/out/u/eskatvsd.mpd";
            var dir = @"stream";

            var downloader = new MpdDownloader(new Uri(url), dir);
            var trackRepresentation = downloader.GetTracksFor(TrackContentType.Video).First().TrackRepresentations.OrderByDescending(r => r.Bandwidth).First();
            var path = await downloader.Download(trackRepresentation, TimeSpan.Zero, TimeSpan.FromSeconds(30));

            Console.WriteLine(path);
        }

I get this exception:

'<' is an unexpected token. The expected token is '='. Line 60, position 25.
   at System.Xml.XmlTextReaderImpl.Throw(Exception e)
   at System.Xml.XmlTextReaderImpl.Throw(String res, String[] args)
   at System.Xml.XmlTextReaderImpl.ThrowUnexpectedToken(String expectedToken1, String expectedToken2)
   at System.Xml.XmlTextReaderImpl.ParseAttributes()
   at System.Xml.XmlTextReaderImpl.ParseElement()
   at System.Xml.XmlTextReaderImpl.ParseElementContent()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r)
   at System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r, LoadOptions o)
   at System.Xml.Linq.XElement.ReadElementFrom(XmlReader r, LoadOptions o)
   at System.Xml.Linq.XNode.ReadFrom(XmlReader reader)
   at Qoollo.MpegDash.MediaPresentationDescription.ReadMpdTag()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at System.Lazy`1.get_Value()
   at Qoollo.MpegDash.MediaPresentationDescription.ParsePeriods()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at System.Lazy`1.get_Value()
   at Qoollo.MpegDash.MpdWalker.GetTracksFor(TrackContentType type)
   at Qoollo.MpegDash.MpdDownloader.GetTracksFor(TrackContentType type)
   at MpdStream.Program.<MainAsync>d__1.MoveNext() in c:\users\jsyty\documents\visual studio 2015\Projects\MpdStream\MpdStream\Program.cs:line 24
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at MpdStream.Program.<>c.<<Main>b__0_0>d.MoveNext() in c:\users\jsyty\documents\visual studio 2015\Projects\MpdStream\MpdStream\Program.cs:line 14

The expected token IS = in downloaded xml.

When i checked my stream mpd on http://www.validome.org/xml/validate/ it says it's valid xml.

Can you help me here?

jakoss commented 7 years ago

I found crash reason, just not sure why is that happening.

var stream = File.OpenRead(xmlPath);
            using (var reader = XmlReader.Create(stream))
            {
                stream.Seek(0, SeekOrigin.Begin); // this line crashes everything
                reader.ReadToFollowing("MPD");
                var element = XNode.ReadFrom(reader) as XElement;
            }

When i remove stream.Seek() it works perfectly. But as i understand - this seek to begin is nessesary?

Also - it works if done this way:

var stream = File.OpenRead(xmlPath);
            stream.Seek(0, SeekOrigin.Begin);
            using (var reader = XmlReader.Create(stream))
            {
                reader.ReadToFollowing("MPD");
                var element = XNode.ReadFrom(reader) as XElement;
            }
jamie-lord commented 6 years ago

I came across this bug too. Simply did this instead:

private XElement ReadMpdTag()
        {
            using (_stream)
            {
                _stream.Seek(0, SeekOrigin.Begin);
                return XElement.Load(_stream);
            }
        }
EvAlex commented 6 years ago

I'll look into it

EvAlex commented 6 years ago

@Nekromancer

Well, I managed to fix the issue, but several other issues arose. At the moment I'm stuck with the following part of your MPD file:

<SegmentTemplate timescale="90000" media="457_video_1_3_$Number$.mp4?m=1488453681" initialization="457_video_1_3_init.mp4?m=1488453681" startNumber="8608457">
    <SegmentTimeline>
        <S t="3432264669158" d="720000" r="11"/>
    </SegmentTimeline>
</SegmentTemplate>

I'm having troubles figuring out, which would be the 1st segment url? I'm guessing http://ncplusgo.s43-po.live.e56-po.insyscd.net/out/u/457_video_1_3_8608457.mp4?m=1488453681, but that's 404.

I found online player (http://players.akamai.com/dash/) that starts requests from http://ncplusgo.s43-po.live.e56-po.insyscd.net/out/u/457_video_1_3_8609804.mp4?m=1488453681. But why 8609804? Where does this number come from?

EvAlex commented 6 years ago

@Nekromancer checkout #3 - xml validation problem is fixed there.

I've created a separate issue #4 with PR #5 for SegmentTimeline support

jakoss commented 6 years ago

Hi @EvAlex , that number was generated by website which i got source from. I'm not sure what it means, maybe some kind of checksum for security. I dropped the idea i was following that day, project went into different direction