class OneJpegPerIframe extends AbstractTrack {
    private File[] jpegs;
    private TrackMetaData trackMetaData = new TrackMetaData();
    private long[] sampleDurations;
    private long[] syncSamples;
    private VisualSampleEntry mp4v;


    public OneJpegPerIframe(String name, File[] jpegs, Track alignTo) throws IOException {
        super(name);
        this.jpegs = jpegs;
        if (alignTo.getSyncSamples().length != jpegs.length) {
            throw new RuntimeException("Number of sync samples doesn't match the number of stills (" + alignTo.getSyncSamples().length + " vs. " + jpegs.length + ")");
        }
        BufferedImage a = ImageIO.read(jpegs[0]);
        trackMetaData.setWidth(a.getWidth());
        trackMetaData.setHeight(a.getHeight());
        trackMetaData.setTimescale(alignTo.getTrackMetaData().getTimescale());


        long[] sampleDurationsToiAlignTo = alignTo.getSampleDurations();
        long[] syncSamples = alignTo.getSyncSamples();
        int currentSyncSample = 1;
        long duration = 0;
        sampleDurations = new long[syncSamples.length];

        for (int i = 1; i < sampleDurationsToiAlignTo.length; i++) {
            if (currentSyncSample < syncSamples.length && i == syncSamples[currentSyncSample]) {
                sampleDurations[currentSyncSample - 1] = duration;
                duration = 0;
                currentSyncSample++;
            }
            duration += sampleDurationsToiAlignTo[i];
        }
        sampleDurations[sampleDurations.length - 1] = duration;

        mp4v = new VisualSampleEntry("mp4v");
        ESDescriptorBox esds = new ESDescriptorBox();
        esds.setData(ByteBuffer.wrap(Hex.decodeHex("038080801B000100048080800D6C11000000000A1CB4000A1CB4068080800102")));
        esds.setEsDescriptor((ESDescriptor) ObjectDescriptorFactory.createFrom(-1, ByteBuffer.wrap(Hex.decodeHex("038080801B000100048080800D6C11000000000A1CB4000A1CB4068080800102"))));
        mp4v.addBox(esds);
        this.syncSamples = new long[jpegs.length];
        for (int i = 0; i < this.syncSamples.length; i++) {
            this.syncSamples[i] = i + 1;

        }

        double earliestTrackPresentationTime = 0;
        boolean acceptDwell = true;
        boolean acceptEdit = true;
        for (Edit edit : alignTo.getEdits()) {
            if (edit.getMediaTime() == -1 && !acceptDwell) {
                throw new RuntimeException("Cannot accept edit list for processing (1)");
            }
            if (edit.getMediaTime() >= 0 && !acceptEdit) {
                throw new RuntimeException("Cannot accept edit list for processing (2)");
            }
            if (edit.getMediaTime() == -1) {
                earliestTrackPresentationTime += edit.getSegmentDuration();
            } else /* if edit.getMediaTime() >= 0 */ {
                earliestTrackPresentationTime -= (double) edit.getMediaTime() / edit.getTimeScale();
                acceptEdit = false;
                acceptDwell = false;
            }
        }
        if (alignTo.getCompositionTimeEntries() != null && alignTo.getCompositionTimeEntries().size() > 0) {
            long currentTime = 0;
            int[] ptss = CompositionTimeToSample.blowupCompositionTimes(alignTo.getCompositionTimeEntries());
            for (int j = 0; j < ptss.length && j < 50; j++) {
                ptss[j] += currentTime;
                currentTime += alignTo.getSampleDurations()[j];
            }
            Arrays.sort(ptss);
            earliestTrackPresentationTime += (double) ptss[0] / alignTo.getTrackMetaData().getTimescale();

        }

        if (earliestTrackPresentationTime < 0) {
            getEdits().add(new Edit((long) (-earliestTrackPresentationTime * getTrackMetaData().getTimescale()), getTrackMetaData().getTimescale(), 1.0, (double) getDuration() / getTrackMetaData().getTimescale()));
        } else if (earliestTrackPresentationTime > 0) {
            getEdits().add(new Edit(-1, getTrackMetaData().getTimescale(), 1.0, earliestTrackPresentationTime));
            getEdits().add(new Edit(0, getTrackMetaData().getTimescale(), 1.0, (double) getDuration() / getTrackMetaData().getTimescale()));
        }

    }

    public List<SampleEntry> getSampleEntries() {
        return Collections.<SampleEntry>singletonList(mp4v);
    }

    public long[] getSampleDurations() {
        return sampleDurations;
    }

    public TrackMetaData getTrackMetaData() {
        return trackMetaData;
    }

    public String getHandler() {
        return "vide";
    }

    @Override
    public long[] getSyncSamples() {
        return syncSamples;
    }


    public List<Sample> getSamples() {<FILL_FUNCTION_BODY>}

    public void close() throws IOException {

    }
}

        return new AbstractList<Sample>() {

            @Override
            public int size() {
                return jpegs.length;
            }

            @Override
            public Sample get(final int index) {
                return new Sample() {
                    ByteBuffer sample = null;

                    public void writeTo(WritableByteChannel channel) throws IOException {
                        RandomAccessFile raf = new RandomAccessFile(jpegs[index], "r");
                        raf.getChannel().transferTo(0, raf.length(), channel);
                        raf.close();
                    }

                    public long getSize() {
                        return jpegs[index].length();
                    }

                    public ByteBuffer asByteBuffer() {
                        if (sample == null) {
                            try {
                                RandomAccessFile raf = new RandomAccessFile(jpegs[index], "r");
                                sample = raf.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, raf.length());
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        }
                        return sample;
                    }

                    @Override
                    public SampleEntry getSampleEntry() {
                        return mp4v;
                    }
                };
            }
        };
    
<methods>public void <init>(java.lang.String) ,public List<org.mp4parser.boxes.iso14496.part12.CompositionTimeToSample.Entry> getCompositionTimeEntries() ,public long getDuration() ,public List<org.mp4parser.muxer.Edit> getEdits() ,public java.lang.String getName() ,public List<org.mp4parser.boxes.iso14496.part12.SampleDependencyTypeBox.Entry> getSampleDependencies() ,public Map<org.mp4parser.boxes.samplegrouping.GroupEntry,long[]> getSampleGroups() ,public org.mp4parser.boxes.iso14496.part12.SubSampleInformationBox getSubsampleInformationBox() ,public long[] getSyncSamples() <variables>List<org.mp4parser.muxer.Edit> edits,java.lang.String name,Map<org.mp4parser.boxes.samplegrouping.GroupEntry,long[]> sampleGroups