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 import com.liferay.portal.kernel.util.PropsKeys;
020
021 import com.xuggle.xuggler.IAudioResampler;
022 import com.xuggle.xuggler.IAudioSamples;
023 import com.xuggle.xuggler.ICodec;
024 import com.xuggle.xuggler.IContainer;
025 import com.xuggle.xuggler.IPacket;
026 import com.xuggle.xuggler.IStream;
027 import com.xuggle.xuggler.IStreamCoder;
028
029 import java.util.Properties;
030
031
037 public class LiferayAudioConverter extends LiferayConverter {
038
039 public LiferayAudioConverter(
040 String inputURL, String outputURL, String audioContainer,
041 Properties audioProperties) {
042
043 _inputURL = inputURL;
044 _outputURL = outputURL;
045 _audioContainer = audioContainer;
046
047 initAudioBitRate(audioProperties);
048 initAudioSampleRate(audioProperties);
049 }
050
051 @Override
052 public void convert() throws Exception {
053 try {
054 doConvert();
055 }
056 finally {
057 if (_inputIContainer.isOpened()) {
058 _inputIContainer.close();
059 }
060
061 if (_outputIContainer.isOpened()) {
062 _outputIContainer.close();
063 }
064 }
065 }
066
067 protected void doConvert() throws Exception {
068 _inputIContainer = IContainer.make();
069 _outputIContainer = IContainer.make();
070
071 openContainer(_inputIContainer, _inputURL, false);
072 openContainer(_outputIContainer, _outputURL, true);
073
074 int inputStreamsCount = _inputIContainer.getNumStreams();
075
076 if (inputStreamsCount < 0) {
077 throw new RuntimeException("Input URL does not have any streams");
078 }
079
080 IAudioResampler[] iAudioResamplers =
081 new IAudioResampler[inputStreamsCount];
082
083 IAudioSamples[] inputIAudioSamples =
084 new IAudioSamples[inputStreamsCount];
085 IAudioSamples[] outputIAudioSamples =
086 new IAudioSamples[inputStreamsCount];
087
088 IStream[] outputIStreams = new IStream[inputStreamsCount];
089
090 IStreamCoder[] inputIStreamCoders = new IStreamCoder[inputStreamsCount];
091 IStreamCoder[] outputIStreamCoders =
092 new IStreamCoder[inputStreamsCount];
093
094 for (int i = 0; i < inputStreamsCount; i++) {
095 IStream inputIStream = _inputIContainer.getStream(i);
096
097 IStreamCoder inputIStreamCoder = inputIStream.getStreamCoder();
098
099 inputIStreamCoders[i] = inputIStreamCoder;
100
101 ICodec.Type inputICodecType = inputIStreamCoder.getCodecType();
102
103 if (inputICodecType == ICodec.Type.CODEC_TYPE_AUDIO) {
104 prepareAudio(
105 iAudioResamplers, inputIAudioSamples, outputIAudioSamples,
106 inputIStreamCoder, outputIStreamCoders, _outputIContainer,
107 outputIStreams, inputICodecType, _outputURL, i);
108 }
109
110 openStreamCoder(inputIStreamCoders[i]);
111 openStreamCoder(outputIStreamCoders[i]);
112 }
113
114 if (_outputIContainer.writeHeader() < 0) {
115 throw new RuntimeException("Unable to write container header");
116 }
117
118 IPacket inputIPacket = IPacket.make();
119 IPacket outputIPacket = IPacket.make();
120
121 int previousPacketSize = -1;
122
123 _inputIContainer.readNextPacket(inputIPacket);
124
125 while (_inputIContainer.readNextPacket(inputIPacket) == 0) {
126 if (_log.isDebugEnabled()) {
127 _log.debug("Current packet size " + inputIPacket.getSize());
128 }
129
130 int streamIndex = inputIPacket.getStreamIndex();
131
132 IStreamCoder inputIStreamCoder = inputIStreamCoders[streamIndex];
133 IStreamCoder outputIStreamCoder = outputIStreamCoders[streamIndex];
134
135 if (outputIStreamCoder == null) {
136 continue;
137 }
138
139 if (inputIStreamCoder.getCodecType() ==
140 ICodec.Type.CODEC_TYPE_AUDIO) {
141
142 IStream iStream = _inputIContainer.getStream(streamIndex);
143
144 long timeStampOffset = getStreamTimeStampOffset(iStream);
145
146 decodeAudio(
147 iAudioResamplers[streamIndex],
148 inputIAudioSamples[streamIndex],
149 outputIAudioSamples[streamIndex], inputIPacket,
150 outputIPacket, inputIStreamCoder, outputIStreamCoder,
151 _outputIContainer, inputIPacket.getSize(),
152 previousPacketSize, streamIndex, timeStampOffset);
153 }
154
155 previousPacketSize = inputIPacket.getSize();
156 }
157
158 flush(outputIStreamCoders, _outputIContainer);
159
160 if (_outputIContainer.writeTrailer() < 0) {
161 throw new RuntimeException(
162 "Unable to write trailer to output file");
163 }
164
165 cleanUp(iAudioResamplers, null);
166 cleanUp(inputIAudioSamples, outputIAudioSamples);
167 cleanUp(inputIStreamCoders, outputIStreamCoders);
168 cleanUp(inputIPacket, outputIPacket);
169 }
170
171 @Override
172 protected int getAudioBitRate(ICodec outputICodec, int originalBitRate) {
173 return getProperty(originalBitRate, _audioBitRate, AUDIO_BIT_RATE_MAX);
174 }
175
176 @Override
177 protected int getAudioSampleRate() {
178 return _audioSampleRate;
179 }
180
181 @Override
182 protected IContainer getInputIContainer() {
183 return _inputIContainer;
184 }
185
186 protected void initAudioBitRate(Properties audioProperties) {
187 _audioBitRate = getProperty(
188 audioProperties, PropsKeys.DL_FILE_ENTRY_PREVIEW_AUDIO_BIT_RATE,
189 "audio bit rate", _audioContainer, AUDIO_BIT_RATE_DEFAULT,
190 AUDIO_BIT_RATE_MAX);
191 }
192
193 protected void initAudioSampleRate(Properties audioProperties) {
194 _audioSampleRate = getProperty(
195 audioProperties, PropsKeys.DL_FILE_ENTRY_PREVIEW_AUDIO_SAMPLE_RATE,
196 "audio sample rate", _audioContainer, AUDIO_SAMPLE_RATE_DEFAULT,
197 AUDIO_SAMPLE_RATE_MAX);
198 }
199
200 private static Log _log = LogFactoryUtil.getLog(
201 LiferayAudioConverter.class);
202
203 private int _audioBitRate;
204 private String _audioContainer;
205 private int _audioSampleRate;
206 private IContainer _inputIContainer;
207 private String _inputURL;
208 private IContainer _outputIContainer;
209 private String _outputURL;
210
211 }