1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.google.android.exoplayer2.extractor;
17 
18 import com.google.android.exoplayer2.extractor.flv.FlvExtractor;
19 import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
20 import com.google.android.exoplayer2.extractor.mp3.Mp3Extractor;
21 import com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor;
22 import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
23 import com.google.android.exoplayer2.extractor.ogg.OggExtractor;
24 import com.google.android.exoplayer2.extractor.ts.Ac3Extractor;
25 import com.google.android.exoplayer2.extractor.ts.AdtsExtractor;
26 import com.google.android.exoplayer2.extractor.ts.DefaultTsPayloadReaderFactory;
27 import com.google.android.exoplayer2.extractor.ts.PsExtractor;
28 import com.google.android.exoplayer2.extractor.ts.TsExtractor;
29 import com.google.android.exoplayer2.extractor.wav.WavExtractor;
30 import java.lang.reflect.Constructor;
31 
32 /**
33  * An {@link ExtractorsFactory} that provides an array of extractors for the following formats:
34  *
35  * <ul>
36  * <li>MP4, including M4A ({@link Mp4Extractor})</li>
37  * <li>fMP4 ({@link FragmentedMp4Extractor})</li>
38  * <li>Matroska and WebM ({@link MatroskaExtractor})</li>
39  * <li>Ogg Vorbis/FLAC ({@link OggExtractor}</li>
40  * <li>MP3 ({@link Mp3Extractor})</li>
41  * <li>AAC ({@link AdtsExtractor})</li>
42  * <li>MPEG TS ({@link TsExtractor})</li>
43  * <li>MPEG PS ({@link PsExtractor})</li>
44  * <li>FLV ({@link FlvExtractor})</li>
45  * <li>WAV ({@link WavExtractor})</li>
46  * <li>AC3 ({@link Ac3Extractor})</li>
47  * <li>FLAC (only available if the FLAC extension is built and included)</li>
48  * </ul>
49  */
50 public final class DefaultExtractorsFactory implements ExtractorsFactory {
51 
52   private static final Constructor<? extends Extractor> FLAC_EXTRACTOR_CONSTRUCTOR;
53   static {
54     Constructor<? extends Extractor> flacExtractorConstructor = null;
55     try {
56       flacExtractorConstructor =
57           Class.forName("com.google.android.exoplayer2.ext.flac.FlacExtractor")
58               .asSubclass(Extractor.class).getConstructor();
59     } catch (ClassNotFoundException e) {
60       // Extractor not found.
61     } catch (NoSuchMethodException e) {
62       // Constructor not found.
63     }
64     FLAC_EXTRACTOR_CONSTRUCTOR = flacExtractorConstructor;
65   }
66 
67   private @MatroskaExtractor.Flags int matroskaFlags;
68   private @FragmentedMp4Extractor.Flags int fragmentedMp4Flags;
69   private @Mp3Extractor.Flags int mp3Flags;
70   private @DefaultTsPayloadReaderFactory.Flags int tsFlags;
71 
72   /**
73    * Sets flags for {@link MatroskaExtractor} instances created by the factory.
74    *
75    * @see MatroskaExtractor#MatroskaExtractor(int)
76    * @param flags The flags to use.
77    * @return The factory, for convenience.
78    */
setMatroskaExtractorFlags( @atroskaExtractor.Flags int flags)79   public synchronized DefaultExtractorsFactory setMatroskaExtractorFlags(
80       @MatroskaExtractor.Flags int flags) {
81     this.matroskaFlags = flags;
82     return this;
83   }
84 
85   /**
86    * Sets flags for {@link FragmentedMp4Extractor} instances created by the factory.
87    *
88    * @see FragmentedMp4Extractor#FragmentedMp4Extractor(int)
89    * @param flags The flags to use.
90    * @return The factory, for convenience.
91    */
setFragmentedMp4ExtractorFlags( @ragmentedMp4Extractor.Flags int flags)92   public synchronized DefaultExtractorsFactory setFragmentedMp4ExtractorFlags(
93       @FragmentedMp4Extractor.Flags int flags) {
94     this.fragmentedMp4Flags = flags;
95     return this;
96   }
97 
98   /**
99    * Sets flags for {@link Mp3Extractor} instances created by the factory.
100    *
101    * @see Mp3Extractor#Mp3Extractor(int)
102    * @param flags The flags to use.
103    * @return The factory, for convenience.
104    */
setMp3ExtractorFlags(@p3Extractor.Flags int flags)105   public synchronized DefaultExtractorsFactory setMp3ExtractorFlags(@Mp3Extractor.Flags int flags) {
106     mp3Flags = flags;
107     return this;
108   }
109 
110   /**
111    * Sets flags for {@link DefaultTsPayloadReaderFactory}s used by {@link TsExtractor} instances
112    * created by the factory.
113    *
114    * @see TsExtractor#TsExtractor(int)
115    * @param flags The flags to use.
116    * @return The factory, for convenience.
117    */
setTsExtractorFlags( @efaultTsPayloadReaderFactory.Flags int flags)118   public synchronized DefaultExtractorsFactory setTsExtractorFlags(
119       @DefaultTsPayloadReaderFactory.Flags int flags) {
120     tsFlags = flags;
121     return this;
122   }
123 
124   @Override
createExtractors()125   public synchronized Extractor[] createExtractors() {
126     Extractor[] extractors = new Extractor[FLAC_EXTRACTOR_CONSTRUCTOR == null ? 11 : 12];
127     extractors[0] = new MatroskaExtractor(matroskaFlags);
128     extractors[1] = new FragmentedMp4Extractor(fragmentedMp4Flags);
129     extractors[2] = new Mp4Extractor();
130     extractors[3] = new Mp3Extractor(mp3Flags);
131     extractors[4] = new AdtsExtractor();
132     extractors[5] = new Ac3Extractor();
133     extractors[6] = new TsExtractor(tsFlags);
134     extractors[7] = new FlvExtractor();
135     extractors[8] = new OggExtractor();
136     extractors[9] = new PsExtractor();
137     extractors[10] = new WavExtractor();
138     if (FLAC_EXTRACTOR_CONSTRUCTOR != null) {
139       try {
140         extractors[11] = FLAC_EXTRACTOR_CONSTRUCTOR.newInstance();
141       } catch (Exception e) {
142         // Should never happen.
143         throw new IllegalStateException("Unexpected error creating FLAC extractor", e);
144       }
145     }
146     return extractors;
147   }
148 
149 }
150