public void flattern(MovieBox movie, File video) throws IOException { Platform.deleteFile(video); SeekableByteChannel out = null; try { out = writableChannel(video); flatternChannel(movie, out); } finally { if (out != null) out.close(); } }
public static void main1(String[] args) throws Exception { if (args.length < 2) { System.out.println("Syntax: self <ref movie> <out movie>"); System.exit(-1); } File outFile = new File(args[1]); Platform.deleteFile(outFile); SeekableByteChannel input = null; try { input = readableChannel(new File(args[0])); MovieBox movie = MP4Util.parseMovieChannel(input); new Flattern().flattern(movie, outFile); } finally { if (input != null) input.close(); } }
@Override protected ByteBuffer readPes( SeekableByteChannel ch, long pesPosition, int pesSize, int payloadSize, int pesAbsIdx) throws IOException { ch.position(pesPosition * 188); ByteBuffer buf = NIOUtils.fetchFrom(ch, pesSize * 188); // NOW REMOVE THE TS CRAP ByteBuffer dst = buf.duplicate(); while (buf.hasRemaining()) { ByteBuffer tsBuf = NIOUtils.read(buf, 188); Assert.assertEquals(0x47, tsBuf.get() & 0xff); int guidFlags = ((tsBuf.get() & 0xff) << 8) | (tsBuf.get() & 0xff); int guid = (int) guidFlags & 0x1fff; if (guid == targetGuid) { int b0 = tsBuf.get() & 0xff; int counter = b0 & 0xf; if ((b0 & 0x20) != 0) { NIOUtils.skip(tsBuf, tsBuf.get() & 0xff); } dst.put(tsBuf); } } dst.flip(); readPESHeader(dst, 0); dst.limit(dst.position() + payloadSize); return dst; }
public static void main(String[] args) throws Exception { if (args.length < 2) { System.out.println("Syntax: <in.mov> <out.mov>"); return; } SeekableByteChannel input = readableChannel(new File(args[0])); MP4Demuxer demuxer = new MP4Demuxer(input); SeekableByteChannel output = writableChannel(new File(args[1])); MP4Muxer muxer = MP4Muxer.createMP4Muxer(output, Brand.MOV); AbstractMP4DemuxerTrack inVideo = demuxer.getVideoTrack(); VideoSampleEntry entry = (VideoSampleEntry) inVideo.getSampleEntries()[0]; int width = entry.getWidth(); int height = entry.getHeight(); ProresToProxy toProxy = new ProresToProxy(width, height, 65536); FramesMP4MuxerTrack outVideo = muxer.addTrack(TrackType.VIDEO, (int) inVideo.getTimescale()); TrackHeaderBox th = inVideo.getBox().getTrackHeader(); System.out.println(toProxy.getFrameSize()); int frame = 0; long from = System.currentTimeMillis(); long last = from; MP4Packet pkt = null; while ((pkt = (MP4Packet) inVideo.nextFrame()) != null) { ByteBuffer out = ByteBuffer.allocate(pkt.getData().remaining()); toProxy.transcode(pkt.getData(), out); out.flip(); outVideo.addFrame(MP4Packet.createMP4PacketWithData(pkt, out)); frame++; long cur = System.currentTimeMillis(); if (cur - last > 5000) { System.out.println(((1000 * frame) / (cur - from)) + " fps"); last = cur; } } entry.setMediaType("apco"); outVideo.addSampleEntry(entry); muxer.writeHeader(); output.close(); input.close(); }
public void write(SeekableByteChannel output) throws IOException { ByteBuffer bb = ByteBuffer.allocate(16); write(bb); bb.flip(); output.write(bb); }
public void flatternChannel(MovieBox movie, SeekableByteChannel out) throws IOException { if (!movie.isPureRefMovie(movie)) throw new IllegalArgumentException("movie should be reference"); ByteBuffer buf = ByteBuffer.allocate(16 * 1024 * 1024); FileTypeBox ftyp = FileTypeBox.createFileTypeBox("qt ", 0x20050300, Arrays.asList(new String[] {"qt "})); ftyp.write(buf); long movieOff = buf.position(); movie.write(buf); int extraSpace = calcSpaceReq(movie); Header.createHeader("free", 8 + extraSpace).write(buf); NIOUtils.skip(buf, extraSpace); long mdatOff = buf.position(); Header.createHeader("mdat", 0x100000001L).write(buf); buf.flip(); out.write(buf); SeekableByteChannel[][] inputs = getInputs(movie); TrakBox[] tracks = movie.getTracks(); ChunkReader[] readers = new ChunkReader[tracks.length]; ChunkWriter[] writers = new ChunkWriter[tracks.length]; Chunk[] head = new Chunk[tracks.length]; int totalChunks = 0, writtenChunks = 0, lastProgress = 0; long[] off = new long[tracks.length]; for (int i = 0; i < tracks.length; i++) { readers[i] = new ChunkReader(tracks[i]); totalChunks += readers[i].size(); writers[i] = new ChunkWriter(tracks[i], inputs[i], out); head[i] = readers[i].next(); if (tracks[i].isVideo()) off[i] = 2 * movie.getTimescale(); } while (true) { int min = -1; for (int i = 0; i < readers.length; i++) { if (head[i] == null) continue; if (min == -1) min = i; else { long iTv = movie.rescale(head[i].getStartTv(), tracks[i].getTimescale()) + off[i]; long minTv = movie.rescale(head[min].getStartTv(), tracks[min].getTimescale()) + off[min]; if (iTv < minTv) min = i; } } if (min == -1) break; writers[min].write(head[min]); head[min] = readers[min].next(); writtenChunks++; lastProgress = calcProgress(totalChunks, writtenChunks, lastProgress); } long mdatSize = out.position() - mdatOff; for (int i = 0; i < tracks.length; i++) { writers[i].apply(); } out.setPosition(movieOff); MP4Util.writeMovie(out, movie); long extra = mdatOff - out.position(); if (extra < 0) throw new RuntimeException("Not enough space to write the header"); out.write( (ByteBuffer) ByteBuffer.allocate(8).putInt((int) extra).put(new byte[] {'f', 'r', 'e', 'e'}).flip()); out.setPosition(mdatOff + 8); out.write(ByteBuffer.allocate(8).putLong(mdatSize)); }
public static void main1(String[] args) throws Exception { if (args.length < 1) { System.out.println( "Syntax: cut [-command arg]...[-command arg] [-self] <movie file>\n" + "\tCreates a reference movie out of the file and applies a set of changes specified by the commands to it."); System.exit(-1); } List<Slice> slices = new ArrayList<Slice>(); List<String> sliceNames = new ArrayList<String>(); boolean selfContained = false; int shift = 0; while (true) { if ("-cut".equals(args[shift])) { String[] pt = StringUtils.splitS(args[shift + 1], ":"); slices.add(new Slice(parseInt(pt[0]), parseInt(pt[1]))); if (pt.length > 2) sliceNames.add(pt[2]); else sliceNames.add(null); shift += 2; } else if ("-self".equals(args[shift])) { ++shift; selfContained = true; } else break; } File source = new File(args[shift]); SeekableByteChannel input = null; SeekableByteChannel out = null; List<SeekableByteChannel> outs = new ArrayList<SeekableByteChannel>(); try { input = readableChannel(source); MovieBox movie = createRefMovie(input, "file://" + source.getCanonicalPath()); List<MovieBox> slicesMovs; if (!selfContained) { out = writableChannel( new File( source.getParentFile(), JCodecUtil2.removeExtension(source.getName()) + ".ref.mov")); slicesMovs = new Cut().cut(movie, slices); MP4Util.writeMovie(out, movie); } else { out = writableChannel( new File( source.getParentFile(), JCodecUtil2.removeExtension(source.getName()) + ".self.mov")); slicesMovs = new Cut().cut(movie, slices); new Strip().strip(movie); new Flattern().flatternChannel(movie, out); } saveSlices(slicesMovs, sliceNames, source.getParentFile()); } finally { if (input != null) input.close(); if (out != null) out.close(); for (SeekableByteChannel o : outs) { o.close(); } } }