001
014
015 package com.liferay.portlet.documentlibrary.util;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019
020 import com.xuggle.xuggler.IAudioResampler;
021 import com.xuggle.xuggler.IAudioSamples;
022 import com.xuggle.xuggler.ICodec;
023 import com.xuggle.xuggler.IContainer;
024 import com.xuggle.xuggler.IPacket;
025 import com.xuggle.xuggler.IStream;
026 import com.xuggle.xuggler.IStreamCoder;
027
028
033 public class LiferayAudioConverter extends LiferayConverter {
034
035 public LiferayAudioConverter(String inputURL, String outputURL, int rate) {
036 _inputURL = inputURL;
037 _outputURL = outputURL;
038 _rate = rate;
039 }
040
041 public void convert() throws Exception {
042 try {
043 doConvert();
044 }
045 finally {
046 if (_inputIContainer.isOpened()) {
047 _inputIContainer.close();
048 }
049
050 if (_outputIContainer.isOpened()) {
051 _outputIContainer.close();
052 }
053 }
054 }
055
056 protected void doConvert() throws Exception {
057 _inputIContainer = IContainer.make();
058 _outputIContainer = IContainer.make();
059
060 openContainer(_inputIContainer, _inputURL, false);
061 openContainer(_outputIContainer, _outputURL, true);
062
063 int inputStreamsCount = _inputIContainer.getNumStreams();
064
065 if (inputStreamsCount < 0) {
066 throw new RuntimeException("Input URL does not have any streams");
067 }
068
069 IAudioResampler[] iAudioResamplers =
070 new IAudioResampler[inputStreamsCount];
071
072 IAudioSamples[] inputIAudioSamples =
073 new IAudioSamples[inputStreamsCount];
074 IAudioSamples[] outputIAudioSamples =
075 new IAudioSamples[inputStreamsCount];
076
077 IStream[] outputIStreams = new IStream[inputStreamsCount];
078
079 IStreamCoder[] inputIStreamCoders = new IStreamCoder[inputStreamsCount];
080 IStreamCoder[] outputIStreamCoders =
081 new IStreamCoder[inputStreamsCount];
082
083 for (int i = 0; i < inputStreamsCount; i++) {
084 IStream inputIStream = _inputIContainer.getStream(i);
085
086 IStreamCoder inputIStreamCoder = inputIStream.getStreamCoder();
087
088 inputIStreamCoders[i] = inputIStreamCoder;
089
090 ICodec.Type inputICodecType = inputIStreamCoder.getCodecType();
091
092 if (inputICodecType == ICodec.Type.CODEC_TYPE_AUDIO) {
093 int channels = _channels;
094
095 if (inputIStreamCoder.getChannels() > 0) {
096 channels = inputIStreamCoder.getChannels();
097 }
098
099 int rate = _rate;
100
101 if (inputIStreamCoder.getSampleRate() > 0) {
102 rate = inputIStreamCoder.getSampleRate();
103 }
104
105 prepareAudio(
106 iAudioResamplers, inputIAudioSamples, outputIAudioSamples,
107 inputIStreamCoder, outputIStreamCoders, _outputIContainer,
108 outputIStreams, inputICodecType, _outputURL, channels, rate,
109 i);
110 }
111
112 openStreamCoder(inputIStreamCoders[i]);
113 openStreamCoder(outputIStreamCoders[i]);
114 }
115
116 if (_outputIContainer.writeHeader() < 0) {
117 throw new RuntimeException("Unable to write container header");
118 }
119
120 IPacket inputIPacket = IPacket.make();
121 IPacket outputIPacket = IPacket.make();
122
123 int previousPacketSize = -1;
124
125 _inputIContainer.readNextPacket(inputIPacket);
126
127 while (_inputIContainer.readNextPacket(inputIPacket) == 0) {
128 if (_log.isDebugEnabled()) {
129 _log.debug("Current packet size " + inputIPacket.getSize());
130 }
131
132 int streamIndex = inputIPacket.getStreamIndex();
133
134 IStreamCoder inputIStreamCoder = inputIStreamCoders[streamIndex];
135 IStreamCoder outputIStreamCoder = outputIStreamCoders[streamIndex];
136
137 if (outputIStreamCoder == null) {
138 continue;
139 }
140
141 if (inputIStreamCoder.getCodecType() ==
142 ICodec.Type.CODEC_TYPE_AUDIO) {
143
144 IStream iStream = _inputIContainer.getStream(streamIndex);
145
146 long timeStampOffset = getStreamTimeStampOffset(iStream);
147
148 decodeAudio(
149 iAudioResamplers[streamIndex],
150 inputIAudioSamples[streamIndex],
151 outputIAudioSamples[streamIndex], inputIPacket,
152 outputIPacket, inputIStreamCoder, outputIStreamCoder,
153 _outputIContainer, inputIPacket.getSize(),
154 previousPacketSize, streamIndex, timeStampOffset);
155 }
156
157 previousPacketSize = inputIPacket.getSize();
158 }
159
160 flush(outputIStreamCoders, _outputIContainer);
161
162 if (_outputIContainer.writeTrailer() < 0) {
163 throw new RuntimeException(
164 "Unable to write trailer to output file");
165 }
166
167 cleanUp(inputIStreamCoders, outputIStreamCoders);
168 }
169
170 @Override
171 protected IContainer getInputIContainer() {
172 return _inputIContainer;
173 }
174
175 private static Log _log = LogFactoryUtil.getLog(
176 LiferayAudioConverter.class);
177
178 private int _channels = 1;
179 private IContainer _inputIContainer;
180 private String _inputURL;
181 private IContainer _outputIContainer;
182 private String _outputURL;
183 private int _rate;
184
185 }