public long[] getSampleDurations() { long[] adoptedSampleDuration = new long[sampleDurations.length]; for (int i = 0; i < adoptedSampleDuration.length; i++) { adoptedSampleDuration[i] = sampleDurations[i] * trackMetaData.getTimescale() / 1000; } return adoptedSampleDuration; }
public long[] getSampleDurations() { long[] adoptedSampleDuration = new long[sampleDurations.length]; for (int i = 0; i < adoptedSampleDuration.length; i++) { adoptedSampleDuration[i] = sampleDurations[i] * trackMetaData.getTimescale() / 1000; } return adoptedSampleDuration; }
public long getTimescale(Movie movie) { long timescale = movie.getTracks().iterator().next().getTrackMetaData().getTimescale(); for (Track track : movie.getTracks()) { timescale = lcm(timescale, track.getTrackMetaData().getTimescale()); } return timescale; }
public long getTimescale() { long timescale = this.getTracks().iterator().next().getTrackMetaData().getTimescale(); for (Track track : this.getTracks()) { timescale = gcd(track.getTrackMetaData().getTimescale(), timescale); } return timescale; }
public static void main(String[] args) throws IOException { Movie m = MovieCreator.build("c:\\content\\big_buck_bunny_1080p_h264-2min-handbraked.mp4"); double movieDuration = 0; for (Track track : m.getTracks()) { movieDuration = Math.max((double) track.getDuration() / track.getTrackMetaData().getTimescale(), movieDuration); } // We got the full duration in seconds System.err.println("Bitrate in bit/s: " + (new File("c:\\content\\big_buck_bunny_1080p_h264-2min-handbraked.mp4").length() * 8 /movieDuration)); } }
private static long[] getTimes(Track track, long[] syncSamples, long targetTimeScale) { long[] syncSampleTimes = new long[syncSamples.length]; int currentSample = 1; // first syncsample is 1 long currentDuration = 0; int currentSyncSampleIndex = 0; while (currentSample <= syncSamples[syncSamples.length - 1]) { if (currentSample == syncSamples[currentSyncSampleIndex]) { syncSampleTimes[currentSyncSampleIndex++] = (currentDuration * targetTimeScale) / track.getTrackMetaData().getTimescale(); } currentDuration += track.getSampleDurations()[currentSample - 1]; currentSample++; } return syncSampleTimes; }
private static long calculateTracktimesScalingFactor(Movie m, Track track) { long timeScale = 1; for (Track track1 : m.getTracks()) { if (track1.getHandler().equals(track.getHandler())) { if (track1.getTrackMetaData().getTimescale() != track.getTrackMetaData().getTimescale()) { timeScale = lcm(timeScale, track1.getTrackMetaData().getTimescale()); } } } return timeScale; }
public SilenceTrackImpl(Track ofType, long ms) { source = ofType; name = "" + ms + "ms silence"; assert ofType.getSampleEntries().size() == 1: ""; if ("mp4a".equals(ofType.getSampleEntries().get(0).getType())) { int numFrames = l2i(getTrackMetaData().getTimescale() * ms / 1000 / 1024); decodingTimes = new long[numFrames]; Arrays.fill(decodingTimes, getTrackMetaData().getTimescale() * ms / numFrames / 1000); while (numFrames-- > 0) { samples.add(new SampleImpl((ByteBuffer) ByteBuffer.wrap(new byte[]{ 0x21, 0x10, 0x04, 0x60, (byte) 0x8c, 0x1c, }).rewind(), ofType.getSampleEntries().get(0))); } } else { throw new RuntimeException("Tracks of type " + ofType.getClass().getSimpleName() + " are not supported"); } }
private static long findNextSyncSample(Track track, double cutHere) { long currentSample = 0; double currentTime = 0; long[] durations = track.getSampleDurations(); long[] syncSamples = track.getSyncSamples(); for (int i = 0; i < durations.length; i++) { long delta = durations[i]; if ((syncSamples == null || syncSamples.length > 0 || Arrays.binarySearch(syncSamples, currentSample + 1) >= 0) && currentTime > cutHere) { return i; } currentTime += (double) delta / (double) track.getTrackMetaData().getTimescale(); currentSample++; } return currentSample; }
private static long getTrackDuration(Movie movie, Track track) { return (track.getDuration() * movie.getTimescale()) / track.getTrackMetaData().getTimescale(); }
public TrackMetaData getTrackMetaData() { TrackMetaData trackMetaData = (TrackMetaData) source.getTrackMetaData().clone(); trackMetaData.setTimescale(source.getTrackMetaData().getTimescale() / this.timeScaleDivisor); return trackMetaData; }
public TrackMetaData getTrackMetaData() { TrackMetaData trackMetaData = (TrackMetaData) source.getTrackMetaData().clone(); trackMetaData.setTimescale(source.getTrackMetaData().getTimescale() * this.timeScaleFactor); return trackMetaData; }
/** * {@inheritDoc} */ public long[] sampleNumbers(Track track) { long[] segmentStartSamples = new long[]{1}; long[] sampleDurations = track.getSampleDurations(); long[] syncSamples = track.getSyncSamples(); long timescale = track.getTrackMetaData().getTimescale(); double time = 0; for (int i = 0; i < sampleDurations.length; i++) { time += (double) sampleDurations[i] / timescale; if (time >= fragmentLength && (syncSamples == null || Arrays.binarySearch(syncSamples, i + 1) >= 0)) { if (i > 0) { segmentStartSamples = Mp4Arrays.copyOfAndAppend(segmentStartSamples, i + 1); } time = 0; } } return segmentStartSamples; } }
private static double correctTimeToSyncSample(Track track, double cutHere, boolean next) { double[] timeOfSyncSamples = new double[track.getSyncSamples().length]; long currentSample = 0; double currentTime = 0; for (int i = 0; i < track.getSampleDurations().length; i++) { long delta = track.getSampleDurations()[i]; if (Arrays.binarySearch(track.getSyncSamples(), currentSample + 1) >= 0) { // samples always start with 1 but we start with zero therefore +1 timeOfSyncSamples[Arrays.binarySearch(track.getSyncSamples(), currentSample + 1)] = currentTime; } currentTime += (double) delta / (double) track.getTrackMetaData().getTimescale(); currentSample++; } double previous = 0; for (double timeOfSyncSample : timeOfSyncSamples) { if (timeOfSyncSample > cutHere) { if (next) { return timeOfSyncSample; } else { return previous; } } previous = timeOfSyncSample; } return timeOfSyncSamples[timeOfSyncSamples.length - 1]; }
private static double correctTimeToSyncSample(Track track, double cutHere, boolean next) { double[] timeOfSyncSamples = new double[track.getSyncSamples().length]; long currentSample = 0; double currentTime = 0; for (int i = 0; i < track.getSampleDurations().length; i++) { long delta = track.getSampleDurations()[i]; if (Arrays.binarySearch(track.getSyncSamples(), currentSample + 1) >= 0) { // samples always start with 1 but we start with zero therefore +1 timeOfSyncSamples[Arrays.binarySearch(track.getSyncSamples(), currentSample + 1)] = currentTime; } currentTime += (double) delta / (double) track.getTrackMetaData().getTimescale(); currentSample++; } double previous = 0; for (double timeOfSyncSample : timeOfSyncSamples) { if (timeOfSyncSample > cutHere) { if (next) { return timeOfSyncSample; } else { return previous; } } previous = timeOfSyncSample; } return timeOfSyncSamples[timeOfSyncSamples.length - 1]; }
private static double correctTimeToSyncSample(Track track, double cutHere, boolean next) { double[] timeOfSyncSamples = new double[track.getSyncSamples().length]; long currentSample = 0; double currentTime = 0; for (int i = 0; i < track.getSampleDurations().length; i++) { long delta = track.getSampleDurations()[i]; if (Arrays.binarySearch(track.getSyncSamples(), currentSample + 1) >= 0) { // samples always start with 1 but we start with zero therefore +1 timeOfSyncSamples[Arrays.binarySearch(track.getSyncSamples(), currentSample + 1)] = currentTime; } currentTime += (double) delta / (double) track.getTrackMetaData().getTimescale(); currentSample++; } double previous = 0; for (double timeOfSyncSample : timeOfSyncSamples) { if (timeOfSyncSample > cutHere) { if (next) { return timeOfSyncSample; } else { return previous; } } previous = timeOfSyncSample; } return timeOfSyncSamples[timeOfSyncSamples.length - 1]; }
protected ParsableBox createEdts(Track track, Movie movie) { if (track.getEdits() != null && track.getEdits().size() > 0) { EditListBox elst = new EditListBox(); elst.setVersion(0); // quicktime won't play file when version = 1 List<EditListBox.Entry> entries = new ArrayList<EditListBox.Entry>(); for (Edit edit : track.getEdits()) { entries.add(new EditListBox.Entry(elst, Math.round(edit.getSegmentDuration() * movie.getTimescale()), edit.getMediaTime() * track.getTrackMetaData().getTimescale() / edit.getTimeScale(), edit.getMediaRate())); } elst.setEntries(entries); EditBox edts = new EditBox(); edts.addBox(elst); return edts; } else { return null; } }
/** * Changes the time scale of the source track to the target time scale and makes sure * that any rounding errors that may have summed are corrected exactly before the syncSamples. * * @param source the source track * @param targetTimeScale the resulting time scale of this track. * @param syncSamples at these sync points where rounding error are corrected. */ public ChangeTimeScaleTrack(Track source, long targetTimeScale, long[] syncSamples) { this.source = source; this.timeScale = targetTimeScale; double timeScaleFactor = (double) targetTimeScale / source.getTrackMetaData().getTimescale(); ctts = adjustCtts(source.getCompositionTimeEntries(), timeScaleFactor); decodingTimes = adjustTts(source.getSampleDurations(), timeScaleFactor, syncSamples, getTimes(source, syncSamples, targetTimeScale)); }
protected ParsableBox createEdts(Track track, Movie movie) { if (track.getEdits() != null && track.getEdits().size() > 0) { EditListBox elst = new EditListBox(); elst.setVersion(1); List<EditListBox.Entry> entries = new ArrayList<EditListBox.Entry>(); for (Edit edit : track.getEdits()) { entries.add(new EditListBox.Entry(elst, Math.round(edit.getSegmentDuration() * movie.getTimescale()), edit.getMediaTime() * track.getTrackMetaData().getTimescale() / edit.getTimeScale(), edit.getMediaRate())); } elst.setEntries(entries); EditBox edts = new EditBox(); edts.addBox(elst); return edts; } else { return null; } }
protected ParsableBox createMdhd(Movie movie, Track track) { MediaHeaderBox mdhd = new MediaHeaderBox(); mdhd.setCreationTime(track.getTrackMetaData().getCreationTime()); mdhd.setModificationTime(getDate()); mdhd.setDuration(0);//no duration in moov for fragmented movies mdhd.setTimescale(track.getTrackMetaData().getTimescale()); mdhd.setLanguage(track.getTrackMetaData().getLanguage()); return mdhd; }