FileDocCategorySizeDatePackage
SmoothStreamingTrack.javaAPI Docmp4parser 1.0-RC-179338Wed Dec 19 20:10:21 GMT 2012com.googlecode.mp4parser.tools.smoothstreamingdownloader

SmoothStreamingTrack

public class SmoothStreamingTrack extends Object implements com.googlecode.mp4parser.authoring.Track

Fields Summary
String
fourCC
String
codecPrivateData
com.googlecode.mp4parser.authoring.TrackMetaData
trackMetaData
List
fragments
Constructors Summary
public SmoothStreamingTrack(URI manifestFile, String type, String bitRate)


              
        Builder parser = new Builder();
        Document doc = parser.build(manifestFile.toASCIIString());
        Nodes levelNodes = doc.query(String.format("/SmoothStreamingMedia/StreamIndex[@Type='%s']/QualityLevel[@Bitrate=%s]", type, bitRate));
        Nodes fragments = doc.query(String.format("/SmoothStreamingMedia/StreamIndex[@Type='%s']/c", type));
        if (levelNodes.size() != 1) {
            throw new IOException("Something's wrong");
        }
        Element level = (Element) levelNodes.get(0);
        fourCC = level.getAttribute("FourCC").getValue();
        codecPrivateData = level.getAttribute("CodecPrivateData").getValue();

        trackMetaData = new TrackMetaData();
        if ("avc1".equalsIgnoreCase(fourCC)) {
            // video!
            trackMetaData.setHeight(Double.parseDouble(level.getAttribute("MaxHeight").getValue()));
            trackMetaData.setWidth(Double.parseDouble(level.getAttribute("MaxWidth").getValue()));
            trackMetaData.setTimescale(10000000L); // That's the default but it may be some other value
        }

        String url = ((Element) level.getParent()).getAttribute("Url").getValue();
        long time = 0;
        for (int i = 0; i < fragments.size(); i++) {
            URI fragment = manifestFile.resolve(url.replace("{bitrate}", bitRate).replace("{start time}", Long.toString(time)));
            this.fragments.add(new IsoFile(Channels.newChannel(fragment.toURL().openStream())));
            time += Long.parseLong(((Element) fragments.get(i)).getAttribute("d").getValue());
        }


    
Methods Summary
private java.nio.ByteBufferfindNextNal(java.nio.ByteBuffer bb)

        byte[] test = new byte[]{-1, -1, -1, -1};
        int start = -1;

        int c;
        while ((c = bb.get()) != -1) {
            test[0] = test[1];
            test[1] = test[2];
            test[2] = test[3];
            test[3] = (byte) c;
            if (test[0] == 0 && test[1] == 0 && test[2] == 0 && test[3] == 1) {

                if (start == -1) {
                    start = bb.position();
                    test = new byte[]{-1, -1, -1, -1};
                } else {
                    break;
                }

            }
        }
        if (test[0] == 0 && test[1] == 0 && test[2] == 0 && test[3] == 1) {
            bb.position(bb.position() - 4);
        }
        int length = bb.position() - start;
        ByteBuffer nu = bb.duplicate();
        nu.position(start);
        nu.slice();
        nu.limit(length);
        return nu;
    
public java.util.ListgetCompositionTimeEntries()

        List<CompositionTimeToSample.Entry> entries = new LinkedList<CompositionTimeToSample.Entry>();
        for (IsoFile fragment : fragments) {
            TrackRunBox trun = (TrackRunBox) Path.getPath(fragment, "/moof[0]/traf[0]/trun[0]");
            for (TrackRunBox.Entry entry : trun.getEntries()) {
                entries.add(new CompositionTimeToSample.Entry(entry.getSampleCompositionTimeOffset(), 1));
            }
        }
        return entries;
    
public java.util.ListgetDecodingTimeEntries()

        List<TimeToSampleBox.Entry> entries = new LinkedList<TimeToSampleBox.Entry>();
        for (IsoFile fragment : fragments) {
            TrackRunBox trun = (TrackRunBox) Path.getPath(fragment, "/moof[0]/traf[0]/trun[0]");
            for (TrackRunBox.Entry entry : trun.getEntries()) {
                entries.add(new TimeToSampleBox.Entry(entry.getSampleDuration(), 1));
            }
        }
        return entries;

    
public java.lang.StringgetHandler()

        if ("avc1".equalsIgnoreCase(fourCC)) {
            return "vide";
        }
        throw new RuntimeException();
    
public BoxgetMediaHeaderBox()

        if ("avc1".equalsIgnoreCase(fourCC)) {
            return new VideoMediaHeaderBox();

        }
        throw new RuntimeException();
    
public java.util.ListgetSampleDependencies()

        return null; // no sample dependencies for us
    
public SampleDescriptionBoxgetSampleDescriptionBox()

        SampleDescriptionBox stsd = new SampleDescriptionBox();
        if ("avc1".equalsIgnoreCase(fourCC)) {
            VisualSampleEntry vse = new VisualSampleEntry("avc1");
            vse.setHorizresolution((int) trackMetaData.getWidth());
            vse.setHeight((int) trackMetaData.getHeight());


            AvcConfigurationBox avcC = new AvcConfigurationBox();
            vse.addBox(avcC);
            AvcConfigurationBox.AVCDecoderConfigurationRecord record = new AvcConfigurationBox.AVCDecoderConfigurationRecord();
            ByteBuffer spsAndPps = ByteBuffer.wrap(Hex.decodeHex(codecPrivateData));

            ByteBuffer allSequenceParameterSets = findNextNal(spsAndPps);
            List<byte[]> sequenceParameterSets = new LinkedList<byte[]>();
            allSequenceParameterSets.position(0);
            while (allSequenceParameterSets.position() <= allSequenceParameterSets.limit()) {
                int length = IsoTypeReader.readUInt16(allSequenceParameterSets);
                sequenceParameterSets.add((byte[]) allSequenceParameterSets.duplicate().slice().limit(length).array());
                allSequenceParameterSets.position(allSequenceParameterSets.position() + length);
            }

            ByteBuffer allPictureParameterSets = findNextNal(spsAndPps);
            List<byte[]> pictureParameterSets = new LinkedList<byte[]>();
            allPictureParameterSets.position(0);
            while (allPictureParameterSets.position() <= allPictureParameterSets.limit()) {
                int length = IsoTypeReader.readUInt16(allPictureParameterSets);
                pictureParameterSets.add((byte[]) allPictureParameterSets.duplicate().slice().limit(length).array());
                allPictureParameterSets.position(allPictureParameterSets.position() + length);
            }

            avcC.setSequenceParameterSets(sequenceParameterSets);
            avcC.setPictureParameterSets(pictureParameterSets);
            stsd.addBox(vse);
        }
        return stsd;
    
public java.util.ListgetSamples()

        List<ByteBuffer> samples = new ArrayList<ByteBuffer>();
        for (IsoFile fragment : fragments) {
            TrackFragmentBox traf = (TrackFragmentBox) Path.getPath(fragment, "/moof[0]/traf[0]");
            samples.addAll(new SampleList(traf));
        }
        return samples;
    
public SubSampleInformationBoxgetSubsampleInformationBox()

        return null; // no subsamples for us
    
public long[]getSyncSamples()

        int numSyncSamples = 0;
        for (IsoFile fragment : fragments) {
            TrackRunBox trun = (TrackRunBox) Path.getPath(fragment, "/moof[0]/traf[0]/trun[0]");
            for (TrackRunBox.Entry entry : trun.getEntries()) {
                if (!entry.getSampleFlags().isSampleIsDifferenceSample()) {
                    numSyncSamples++;
                }
            }
        }
        long[] syncSamples = new long[numSyncSamples];
        int sampleNum = 1;
        int syncSampleNum = 0;
        for (IsoFile fragment : fragments) {
            TrackRunBox trun = (TrackRunBox) Path.getPath(fragment, "/moof[0]/traf[0]/trun[0]");
            for (TrackRunBox.Entry entry : trun.getEntries()) {
                if (!entry.getSampleFlags().isSampleIsDifferenceSample()) {
                    syncSamples[syncSampleNum++] = sampleNum;
                }
                sampleNum++;
            }
        }
        return syncSamples;

    
public com.googlecode.mp4parser.authoring.TrackMetaDatagetTrackMetaData()

        return trackMetaData;
    
public booleanisEnabled()

        return true;
    
public booleanisInMovie()

        return true;
    
public booleanisInPoster()

        return true;
    
public booleanisInPreview()

        return true;