/* * myLib - https://github.com/taktod/myLib * Copyright (c) 2014 ttProject. All rights reserved. * * Licensed under The MIT license. */ package com.ttProject.frame.opus.type; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import com.ttProject.frame.opus.OpusFrame; import com.ttProject.nio.channels.ByteReadChannel; import com.ttProject.nio.channels.IReadChannel; import com.ttProject.util.BufferUtil; /** * commentFrame * (ogg do have.webm not.) * OpusTags * venderLength: * venderData * elementNum * Data1Length * Data1Data * Data2Length * Data2Data * .... * for the convert from webm(mkv) -> ogg, need to make up. * @author taktod */ public class CommentFrame extends OpusFrame { /** logger */ private Logger logger = Logger.getLogger(CommentFrame.class); private String opusString = "OpusTags"; private String venderName; private Integer elementSize = null; private List<String> elementList = new ArrayList<String>(); private ByteBuffer tmpBuffer = null; /** * constructor */ public CommentFrame() { super.update(); } @Override public void minimumLoad(IReadChannel channel) throws Exception { super.setReadPosition(channel.position()); super.setSize(channel.size()); super.update(); } @Override public void load(IReadChannel channel) throws Exception { IReadChannel targetChannel = null; if(tmpBuffer != null) { tmpBuffer = BufferUtil.connect( tmpBuffer, BufferUtil.safeRead(channel, channel.size() - channel.position()) ); targetChannel = new ByteReadChannel(tmpBuffer); tmpBuffer = null; } else { targetChannel = channel; } if(venderName == null) { venderName = readString(targetChannel); if(venderName == null) { return; } logger.info("venderName:" + venderName); } if(elementSize == null) { Integer size = readInt(targetChannel); if(size == null) { return; } elementSize = size; } for(int i = 0;i < elementSize; i ++) { String element = readString(targetChannel); if(element == null) { return; } elementList.add(element); } logger.info(venderName); logger.info(elementList); super.update(); } /** * readString * @param channel * @return if need more data, return null. */ private String readString(IReadChannel channel) throws Exception { Integer length = readInt(channel); if(length == null) { return null; } if(channel.size() - channel.position() < length) { tmpBuffer = ByteBuffer.allocate(channel.size() - channel.position() + 4); tmpBuffer.order(ByteOrder.LITTLE_ENDIAN); tmpBuffer.putInt(length); tmpBuffer.put(BufferUtil.safeRead(channel, channel.size() - channel.position())); tmpBuffer.flip(); return null; } return new String(BufferUtil.safeRead(channel, length).array()); } /** * read int * @param channel * @return if need more data, return null */ private Integer readInt(IReadChannel channel) throws Exception { if(channel.size() - channel.position() < 4) { tmpBuffer = BufferUtil.safeRead(channel, channel.size() - channel.position()); return null; } ByteBuffer buffer = BufferUtil.safeRead(channel, 4); buffer.order(ByteOrder.LITTLE_ENDIAN); return buffer.getInt(); } /** * {@inheritDoc} */ @Override public ByteBuffer getPackBuffer() throws Exception { return null; } /** * {@inheritDoc} */ @Override protected void requestUpdate() throws Exception { if(venderName == null) { venderName = "myLib.opus.muxer"; } int size = 8 + 4 + venderName.length() + 4; for(String element : elementList) { size += 4 + element.length(); } ByteBuffer buffer = ByteBuffer.allocate(size); buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.put(opusString.getBytes()); buffer.putInt(venderName.length()); buffer.put(venderName.getBytes()); buffer.putInt(elementList.size()); for(String element : elementList) { buffer.putInt(element.length()); buffer.put(element.getBytes()); } buffer.flip(); setSize(buffer.remaining()); setData(buffer); } public void setVenderName(String name) { this.venderName = name; super.update(); } public void addElement(String data) { elementList.add(data); elementSize = elementList.size(); super.update(); } public void removeElement(String data) { elementList.remove(data); elementSize = elementList.size(); super.update(); } /** * {@inheritDoc} */ @Override public boolean isComplete() { return venderName != null && elementSize != null && elementSize == elementList.size(); } }