Debugging more video streaming. Works without regenerating onMetadata.

This commit is contained in:
Knut Forkalsrud 2011-07-09 18:19:48 -07:00
parent 494c0e5930
commit a58b074873
4 changed files with 60 additions and 22 deletions

View file

@ -46,6 +46,7 @@ public class FlvFilter extends OutputStream {
private FlvMetadata metadata;
private FlvMetadata extraMetadata;
private int bodyLen = 0;
public FlvFilter(FlvReceiver receiver, FlvMetadata metadata) {
this.receiver = receiver;
@ -151,7 +152,7 @@ public class FlvFilter extends OutputStream {
headerWritten = true;
} else {
log.warn("SCRIPTDATA out of order");
receiver.writeBody(currentBox);
writeBody();
}
} else if (currentTagType == FLV_TAG_VIDEO || currentTagType == FLV_TAG_AUDIO) {
if (!headerWritten) {
@ -166,14 +167,21 @@ public class FlvFilter extends OutputStream {
} else { // currentTagType == FLV_TAG_AUDIO
metadata.addAudioFrame(currentTagPos, currentTagTimestamp);
}
receiver.writeBody(currentBox);
metadata.setFileSize(currentTagPos + currentTagSize);
writeBody();
} else {
log.error("Unknown box type: " + currentTagType);
receiver.writeBody(currentBox);
writeBody();
}
}
/**
*
*/
private void writeBody() {
receiver.writeBody(currentBox);
bodyLen += currentBox.length;
}
@Override
public void flush() throws IOException {
@ -184,9 +192,11 @@ public class FlvFilter extends OutputStream {
public void generateHeader() throws IOException {
metadata.setFileSize(fileHeader.length + incomingMetadataLength + bodyLen);
int metadataLength = metadata.calculateLength();
ByteArrayOutputStream out = new ByteArrayOutputStream(fileHeader.length + metadataLength);
out.write(fileHeader);
metadata.setFileSize(fileHeader.length + metadataLength + bodyLen);
metadata.setFileOffsetDelta(metadataLength - incomingMetadataLength);
metadata.writeOnMetadata(out);

View file

@ -149,17 +149,17 @@ public class MovieCoder {
class EncodingProcess implements Runnable, FlvFilter.FlvReceiver {
final int chunkSize = 4 * 65536;
File file;
Thumbnail thumbnail;
Dimension targetSize;
ArrayList<EncodingProcessListener> listeners = new ArrayList<EncodingProcessListener>();
Chunk currentChunk = null;
int chunkPos;
int remainingCapacity;
int chunkNo = 0;
FlvFilter filter;
String dbKey;
private final int chunkSize = 4 * 65536;
private File file;
private Thumbnail thumbnail;
private Dimension targetSize;
private ArrayList<EncodingProcessListener> listeners = new ArrayList<EncodingProcessListener>();
private Chunk currentChunk = null;
private int chunkPos;
private int remainingCapacity;
private int chunkNo = 0;
private FlvFilter filter;
private String dbKey;
public EncodingProcess(File file, Thumbnail thumbnail, Dimension size) {
this.file = file;
@ -219,7 +219,7 @@ public class MovieCoder {
p.getOutputStream().close();
InputStream movieStream = p.getInputStream();
InputStream diagnostic = p.getErrorStream();
new Thread(new ErrorStreamPumper(diagnostic)).start();
new Thread(new ErrorStreamPumper("ffmpeg", diagnostic)).start();
byte[] buffer = new byte[65536];
int len;
@ -228,6 +228,9 @@ public class MovieCoder {
}
filter.flush();
endLastChunk();
// Generate header again to get updated metadata
// TODO (knut 09 JUL 2011) Figure out why the generated header doesn't work
// filter.generateHeader();
} catch (Exception e) {
log.error("uh?", e);
movieDb.delete(dbKey);
@ -282,6 +285,7 @@ public class MovieCoder {
System.arraycopy(data, inputPos, currentChunk.bits, chunkPos, copyLen);
chunkPos += copyLen;
remainingCapacity -= copyLen;
inputPos += copyLen;
remainingInput -= copyLen;
if (remainingCapacity == 0) {
endChunk();
@ -299,6 +303,7 @@ public class MovieCoder {
private void endChunk() {
log.info("Receiving chunk " + chunkNo);
movieDb.store(dbKey, chunkNo, currentChunk);
currentChunk = null;
notifyListeners(chunkNo, false);
@ -328,18 +333,22 @@ public class MovieCoder {
class ErrorStreamPumper implements Runnable {
InputStream is;
public ErrorStreamPumper(InputStream is) {
private InputStream is;
private String name;
public ErrorStreamPumper(String processName, InputStream is) {
this.name = processName;
this.is = is;
}
@Override
public void run() {
org.slf4j.Logger diag = org.slf4j.LoggerFactory.getLogger(this.name);
try {
LineNumberReader lnr = new LineNumberReader(new InputStreamReader(is));
String line;
while ((line = lnr.readLine()) != null) {
log.info(line);
diag.info(line);
}
} catch (Exception e) {
log.error("stderr?", e);
@ -352,7 +361,11 @@ public class MovieCoder {
// range requests etcetera
public void stream(File file, Thumbnail thumbnail, String size, OutputStream out) throws IOException, InterruptedException {
grabStream(file, thumbnail, size).stream(out);
try {
grabStream(file, thumbnail, size).stream(out);
} catch (Exception e) {
log.error("stream fail", e);
}
}
private static String key(File file, Dimension size) {
@ -412,9 +425,17 @@ public class MovieCoder {
public void stream(OutputStream out) throws IOException, InterruptedException {
while (!done()) {
while (chunk != null) {
if (chunk == null) {
log.info("Looking for " + chunkNo);
chunk = movieDb.load(key, chunkNo);
}
if (chunk != null) {
log.info("Sending " + chunkNo + ", " + chunk.bits.length + " bytes");
out.write(chunk.bits);
chunk = movieDb.load(key, ++chunkNo);
chunk = null;
chunkNo++;
continue;
}
if (!done()) {
if (ep != null) {
@ -430,6 +451,7 @@ public class MovieCoder {
if (ep != null) {
ep.removeListener(this);
}
log.info("done sending");
}

View file

@ -344,8 +344,11 @@ public class AlbumServlet
try {
String size = req.getParameter("size");
res.setStatus(HttpServletResponse.SC_OK);
/*
res.setDateHeader("Last-Modified", entry.getPath().lastModified());
res.setDateHeader("Expires", System.currentTimeMillis() + (30 * 24 * 3600 * 1000L)); // 30 days
*/
res.setHeader("Cache-control", "no-cache");
res.setContentType("video/x-flv");
movieCoder.stream(entry.getPath(), entry.getThumbnail(), size, res.getOutputStream());
} catch (Exception ex) {

View file

@ -37,4 +37,7 @@ public class FlvFilterTest extends TestCase {
assertEquals("HEADER[252]BODY[0]HEADER[579]BODY[911684]", buf.toString());
}
public void testFoo() {
System.out.println(0x40128);
}
}