blob: 8efa399b463285425056ec43260e80ed832c65e0 [file] [log] [blame]
/*
* Copyright 2012 Sebastian Annies, Hamburg
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.googlecode.mp4parser.authoring.tracks;
import com.coremedia.iso.boxes.*;
import com.coremedia.iso.boxes.sampleentry.TextSampleEntry;
import com.googlecode.mp4parser.authoring.AbstractTrack;
import com.googlecode.mp4parser.authoring.TrackMetaData;
import com.googlecode.mp4parser.boxes.apple.BaseMediaInfoAtom;
import com.googlecode.mp4parser.boxes.apple.GenericMediaHeaderAtom;
import com.googlecode.mp4parser.boxes.apple.GenericMediaHeaderTextAtom;
import com.googlecode.mp4parser.boxes.apple.QuicktimeTextSampleEntry;
import com.googlecode.mp4parser.boxes.threegpp26245.FontTableBox;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
/**
* A Text track as Quicktime Pro would create.
*/
public class QuicktimeTextTrackImpl extends AbstractTrack {
TrackMetaData trackMetaData = new TrackMetaData();
SampleDescriptionBox sampleDescriptionBox;
List<Line> subs = new LinkedList<Line>();
public List<Line> getSubs() {
return subs;
}
public QuicktimeTextTrackImpl() {
sampleDescriptionBox = new SampleDescriptionBox();
QuicktimeTextSampleEntry textTrack = new QuicktimeTextSampleEntry();
textTrack.setDataReferenceIndex(1);
sampleDescriptionBox.addBox(textTrack);
trackMetaData.setCreationTime(new Date());
trackMetaData.setModificationTime(new Date());
trackMetaData.setTimescale(1000);
}
public List<ByteBuffer> getSamples() {
List<ByteBuffer> samples = new LinkedList<ByteBuffer>();
long lastEnd = 0;
for (Line sub : subs) {
long silentTime = sub.from - lastEnd;
if (silentTime > 0) {
samples.add(ByteBuffer.wrap(new byte[]{0, 0}));
} else if (silentTime < 0) {
throw new Error("Subtitle display times may not intersect");
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
try {
dos.writeShort(sub.text.getBytes("UTF-8").length);
dos.write(sub.text.getBytes("UTF-8"));
dos.close();
} catch (IOException e) {
throw new Error("VM is broken. Does not support UTF-8");
}
samples.add(ByteBuffer.wrap(baos.toByteArray()));
lastEnd = sub.to;
}
return samples;
}
public SampleDescriptionBox getSampleDescriptionBox() {
return sampleDescriptionBox;
}
public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {
List<TimeToSampleBox.Entry> stts = new LinkedList<TimeToSampleBox.Entry>();
long lastEnd = 0;
for (Line sub : subs) {
long silentTime = sub.from - lastEnd;
if (silentTime > 0) {
stts.add(new TimeToSampleBox.Entry(1, silentTime));
} else if (silentTime < 0) {
throw new Error("Subtitle display times may not intersect");
}
stts.add(new TimeToSampleBox.Entry(1, sub.to - sub.from));
lastEnd = sub.to;
}
return stts;
}
public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {
return null;
}
public long[] getSyncSamples() {
return null;
}
public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {
return null;
}
public TrackMetaData getTrackMetaData() {
return trackMetaData;
}
public String getHandler() {
return "text";
}
public static class Line {
long from;
long to;
String text;
public Line(long from, long to, String text) {
this.from = from;
this.to = to;
this.text = text;
}
public long getFrom() {
return from;
}
public String getText() {
return text;
}
public long getTo() {
return to;
}
}
public Box getMediaHeaderBox() {
GenericMediaHeaderAtom ghmd = new GenericMediaHeaderAtom();
ghmd.addBox(new BaseMediaInfoAtom());
ghmd.addBox(new GenericMediaHeaderTextAtom());
return ghmd;
}
public SubSampleInformationBox getSubsampleInformationBox() {
return null;
}
}