如何实现包装 SubtitleDecoderFactory.DEFAULT 的自定义 SubtitleDecoderFactory,这是一个常量实例
How to implement a custom SubtitleDecoderFactory which wraps SubtitleDecoderFactory.DEFAULT, which is a constant instance
我正在学习 Exoplayer,在 https://github.com/google/ExoPlayer/issues/4657 (at the end of the post by erdemguven commented on 24 Aug 2018) regarding creating a wrapper SubtitleDecoderFactory which wraps SubtitleDecoderFactory.DEFAULT (at https://github.com/google/ExoPlayer/blob/release-v2/library/core/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoderFactory.java 找到了一个 post。
在Whosebug的另一个post中,我问了一个关于SubtitleDecoderFactory.DEFAULT的问题,从中我了解到SubtitleDecoderFactory.DEFAULT是一个常量实例。 (在 )
所以我的问题是:
是否需要包装一个常量实例,因为常量实例可以在程序的任何地方看到和引用?
如果需要包装这个常量实例SubtitleDecoderFactory.DEFAULT,代码会怎样?
这是基本接口 SubtitleDecoderFactory(在 https://github.com/google/ExoPlayer/blob/release-v2/library/core/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoderFactory.java):
public interface SubtitleDecoderFactory {
boolean supportsFormat(Format format);
SubtitleDecoder createDecoder(Format format);
SubtitleDecoderFactory DEFAULT =
new SubtitleDecoderFactory() {
@Override
public boolean supportsFormat(Format format) {
@Nullable String mimeType = format.sampleMimeType;
return MimeTypes.TEXT_VTT.equals(mimeType)
|| MimeTypes.TEXT_SSA.equals(mimeType)
|| MimeTypes.APPLICATION_TTML.equals(mimeType)
|| MimeTypes.APPLICATION_MP4VTT.equals(mimeType)
|| MimeTypes.APPLICATION_SUBRIP.equals(mimeType)
|| MimeTypes.APPLICATION_TX3G.equals(mimeType)
|| MimeTypes.APPLICATION_CEA608.equals(mimeType)
|| MimeTypes.APPLICATION_MP4CEA608.equals(mimeType)
|| MimeTypes.APPLICATION_CEA708.equals(mimeType)
|| MimeTypes.APPLICATION_DVBSUBS.equals(mimeType)
|| MimeTypes.APPLICATION_PGS.equals(mimeType);
}
@Override
public SubtitleDecoder createDecoder(Format format) {
@Nullable String mimeType = format.sampleMimeType;
if (mimeType != null) {
switch (mimeType) {
case MimeTypes.TEXT_VTT:
return new WebvttDecoder();
case MimeTypes.TEXT_SSA:
return new SsaDecoder(format.initializationData);
case MimeTypes.APPLICATION_MP4VTT:
return new Mp4WebvttDecoder();
case MimeTypes.APPLICATION_TTML:
return new TtmlDecoder();
case MimeTypes.APPLICATION_SUBRIP:
return new SubripDecoder();
case MimeTypes.APPLICATION_TX3G:
return new Tx3gDecoder(format.initializationData);
case MimeTypes.APPLICATION_CEA608:
case MimeTypes.APPLICATION_MP4CEA608:
return new Cea608Decoder(mimeType, format.accessibilityChannel);
case MimeTypes.APPLICATION_CEA708:
return new Cea708Decoder(format.accessibilityChannel, format.initializationData);
case MimeTypes.APPLICATION_DVBSUBS:
return new DvbDecoder(format.initializationData);
case MimeTypes.APPLICATION_PGS:
return new PgsDecoder();
default:
break;
}
}
throw new IllegalArgumentException(
"Attempted to create decoder for unsupported MIME type: " + mimeType);
}
};
}
我的自定义 SubtitleDecoderFactory 看起来像:
public class mSubtitleDecoderFactory implements SubtitleDecoderFactory{
@Override
public boolean supportsFormat(Format format) {
@Nullable String mimeType = format.sampleMimeType;
return MimeTypes.TEXT_VTT.equals(mimeType)
|| MimeTypes.TEXT_SSA.equals(mimeType)
|| MimeTypes.APPLICATION_TTML.equals(mimeType)
|| MimeTypes.APPLICATION_MP4VTT.equals(mimeType)
|| MimeTypes.APPLICATION_SUBRIP.equals(mimeType)
|| MimeTypes.APPLICATION_TX3G.equals(mimeType)
|| MimeTypes.APPLICATION_CEA608.equals(mimeType)
|| MimeTypes.APPLICATION_MP4CEA608.equals(mimeType)
|| MimeTypes.APPLICATION_CEA708.equals(mimeType)
|| MimeTypes.APPLICATION_DVBSUBS.equals(mimeType)
|| MimeTypes.APPLICATION_PGS.equals(mimeType);
}
@Override
public SubtitleDecoder createDecoder(Format format){
@Nullable String mimeType = format.sampleMimeType;
if (mimeType != null) {
switch (mimeType) {
case MimeTypes.TEXT_VTT:
return new WebvttDecoder();
case MimeTypes.TEXT_SSA:
return new SsaDecoder(format.initializationData);
case MimeTypes.APPLICATION_MP4VTT:
return new Mp4WebvttDecoder();
case MimeTypes.APPLICATION_TTML:
return new TtmlDecoder();
case MimeTypes.APPLICATION_SUBRIP:
return new SubripDecoder();
case MimeTypes.APPLICATION_TX3G:
return new Tx3gDecoder(format.initializationData);
case MimeTypes.APPLICATION_CEA608:
case MimeTypes.APPLICATION_MP4CEA608:
return new Cea608Decoder(mimeType, format.accessibilityChannel);
case MimeTypes.APPLICATION_CEA708:
return new Cea708Decoder(format.accessibilityChannel, format.initializationData);
case MimeTypes.APPLICATION_DVBSUBS:
return new DvbDecoder(format.initializationData);
case MimeTypes.APPLICATION_PGS:
return new PgsDecoder();
default:
break;
}
}
throw new IllegalArgumentException(
"Attempted to create decoder for unsupported MIME type: " + mimeType);
};
};
基本上它覆盖了两个抽象方法 "boolean supportsFormat(Format format)" 和
"SubtitleDecoder createDecoder(Format format)" 在基接口 SubtitleDecoderFactory
中声明
但是要将 SubtitleDecoderFactory.DEFAULT 作为参数放在何处才能进行包装?
提前感谢您的帮助。
据我了解 https://github.com/google/ExoPlayer/issues/4657#issuecomment-415739157,对于您的情况,您需要创建一个具有以下行为的 SubtitleDecoderFactory 实例:
supportsFormat 调用委托给 SubtitleDecoderFactory.DEFAULT
createDecoder 调用使用 SubtitleDecoderFactory.DEFAULT 创建 SubtitleDecoder 实例并将其包装到另一个 SubtitleDecoder 实例(我们将使用匿名 class ),它将除 dequeueOutputBuffer 之外的所有方法委托给包装实例,并且对于 dequeueOutputBuffer 它将使用您的自定义逻辑。
您的代码可能如下所示:
public class mSubtitleDecoderFactory implements SubtitleDecoderFactory{
@Override
public boolean supportsFormat(Format format) {
return SubtitleDecoderFactory.DEFAULT.supportsFormat(format);
}
@Override
public SubtitleDecoder createDecoder(Format format){
SubtitleDecoder wrapped = SubtitleDecoderFactory.DEFAULT.createDecoder(format);
SubtitleDecoder wrapper = new SubtitleDecoder() {
@Override
O dequeueOutputBuffer() throws E {
O resultFromWrapped = wrapped.dequeueOutputBuffer()
// Do what you want with resultFromWrapped and return it modified
}
@Override
String getName() {
return wrapped.getName();
}
@Override
void queueInputBuffer(I inputBuffer) throws E {
wrapped.queueInputBuffer(inputBuffer);
}
// Delegate all other methods
};
return wrapper
}
}
我正在学习 Exoplayer,在 https://github.com/google/ExoPlayer/issues/4657 (at the end of the post by erdemguven commented on 24 Aug 2018) regarding creating a wrapper SubtitleDecoderFactory which wraps SubtitleDecoderFactory.DEFAULT (at https://github.com/google/ExoPlayer/blob/release-v2/library/core/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoderFactory.java 找到了一个 post。
在Whosebug的另一个post中,我问了一个关于SubtitleDecoderFactory.DEFAULT的问题,从中我了解到SubtitleDecoderFactory.DEFAULT是一个常量实例。 (在
所以我的问题是:
是否需要包装一个常量实例,因为常量实例可以在程序的任何地方看到和引用?
如果需要包装这个常量实例SubtitleDecoderFactory.DEFAULT,代码会怎样?
这是基本接口 SubtitleDecoderFactory(在 https://github.com/google/ExoPlayer/blob/release-v2/library/core/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoderFactory.java):
public interface SubtitleDecoderFactory {
boolean supportsFormat(Format format);
SubtitleDecoder createDecoder(Format format);
SubtitleDecoderFactory DEFAULT =
new SubtitleDecoderFactory() {
@Override
public boolean supportsFormat(Format format) {
@Nullable String mimeType = format.sampleMimeType;
return MimeTypes.TEXT_VTT.equals(mimeType)
|| MimeTypes.TEXT_SSA.equals(mimeType)
|| MimeTypes.APPLICATION_TTML.equals(mimeType)
|| MimeTypes.APPLICATION_MP4VTT.equals(mimeType)
|| MimeTypes.APPLICATION_SUBRIP.equals(mimeType)
|| MimeTypes.APPLICATION_TX3G.equals(mimeType)
|| MimeTypes.APPLICATION_CEA608.equals(mimeType)
|| MimeTypes.APPLICATION_MP4CEA608.equals(mimeType)
|| MimeTypes.APPLICATION_CEA708.equals(mimeType)
|| MimeTypes.APPLICATION_DVBSUBS.equals(mimeType)
|| MimeTypes.APPLICATION_PGS.equals(mimeType);
}
@Override
public SubtitleDecoder createDecoder(Format format) {
@Nullable String mimeType = format.sampleMimeType;
if (mimeType != null) {
switch (mimeType) {
case MimeTypes.TEXT_VTT:
return new WebvttDecoder();
case MimeTypes.TEXT_SSA:
return new SsaDecoder(format.initializationData);
case MimeTypes.APPLICATION_MP4VTT:
return new Mp4WebvttDecoder();
case MimeTypes.APPLICATION_TTML:
return new TtmlDecoder();
case MimeTypes.APPLICATION_SUBRIP:
return new SubripDecoder();
case MimeTypes.APPLICATION_TX3G:
return new Tx3gDecoder(format.initializationData);
case MimeTypes.APPLICATION_CEA608:
case MimeTypes.APPLICATION_MP4CEA608:
return new Cea608Decoder(mimeType, format.accessibilityChannel);
case MimeTypes.APPLICATION_CEA708:
return new Cea708Decoder(format.accessibilityChannel, format.initializationData);
case MimeTypes.APPLICATION_DVBSUBS:
return new DvbDecoder(format.initializationData);
case MimeTypes.APPLICATION_PGS:
return new PgsDecoder();
default:
break;
}
}
throw new IllegalArgumentException(
"Attempted to create decoder for unsupported MIME type: " + mimeType);
}
};
}
我的自定义 SubtitleDecoderFactory 看起来像:
public class mSubtitleDecoderFactory implements SubtitleDecoderFactory{
@Override
public boolean supportsFormat(Format format) {
@Nullable String mimeType = format.sampleMimeType;
return MimeTypes.TEXT_VTT.equals(mimeType)
|| MimeTypes.TEXT_SSA.equals(mimeType)
|| MimeTypes.APPLICATION_TTML.equals(mimeType)
|| MimeTypes.APPLICATION_MP4VTT.equals(mimeType)
|| MimeTypes.APPLICATION_SUBRIP.equals(mimeType)
|| MimeTypes.APPLICATION_TX3G.equals(mimeType)
|| MimeTypes.APPLICATION_CEA608.equals(mimeType)
|| MimeTypes.APPLICATION_MP4CEA608.equals(mimeType)
|| MimeTypes.APPLICATION_CEA708.equals(mimeType)
|| MimeTypes.APPLICATION_DVBSUBS.equals(mimeType)
|| MimeTypes.APPLICATION_PGS.equals(mimeType);
}
@Override
public SubtitleDecoder createDecoder(Format format){
@Nullable String mimeType = format.sampleMimeType;
if (mimeType != null) {
switch (mimeType) {
case MimeTypes.TEXT_VTT:
return new WebvttDecoder();
case MimeTypes.TEXT_SSA:
return new SsaDecoder(format.initializationData);
case MimeTypes.APPLICATION_MP4VTT:
return new Mp4WebvttDecoder();
case MimeTypes.APPLICATION_TTML:
return new TtmlDecoder();
case MimeTypes.APPLICATION_SUBRIP:
return new SubripDecoder();
case MimeTypes.APPLICATION_TX3G:
return new Tx3gDecoder(format.initializationData);
case MimeTypes.APPLICATION_CEA608:
case MimeTypes.APPLICATION_MP4CEA608:
return new Cea608Decoder(mimeType, format.accessibilityChannel);
case MimeTypes.APPLICATION_CEA708:
return new Cea708Decoder(format.accessibilityChannel, format.initializationData);
case MimeTypes.APPLICATION_DVBSUBS:
return new DvbDecoder(format.initializationData);
case MimeTypes.APPLICATION_PGS:
return new PgsDecoder();
default:
break;
}
}
throw new IllegalArgumentException(
"Attempted to create decoder for unsupported MIME type: " + mimeType);
};
};
基本上它覆盖了两个抽象方法 "boolean supportsFormat(Format format)" 和 "SubtitleDecoder createDecoder(Format format)" 在基接口 SubtitleDecoderFactory
中声明但是要将 SubtitleDecoderFactory.DEFAULT 作为参数放在何处才能进行包装?
提前感谢您的帮助。
据我了解 https://github.com/google/ExoPlayer/issues/4657#issuecomment-415739157,对于您的情况,您需要创建一个具有以下行为的 SubtitleDecoderFactory 实例:
supportsFormat 调用委托给 SubtitleDecoderFactory.DEFAULT
createDecoder 调用使用 SubtitleDecoderFactory.DEFAULT 创建 SubtitleDecoder 实例并将其包装到另一个 SubtitleDecoder 实例(我们将使用匿名 class ),它将除 dequeueOutputBuffer 之外的所有方法委托给包装实例,并且对于 dequeueOutputBuffer 它将使用您的自定义逻辑。
您的代码可能如下所示:
public class mSubtitleDecoderFactory implements SubtitleDecoderFactory{
@Override
public boolean supportsFormat(Format format) {
return SubtitleDecoderFactory.DEFAULT.supportsFormat(format);
}
@Override
public SubtitleDecoder createDecoder(Format format){
SubtitleDecoder wrapped = SubtitleDecoderFactory.DEFAULT.createDecoder(format);
SubtitleDecoder wrapper = new SubtitleDecoder() {
@Override
O dequeueOutputBuffer() throws E {
O resultFromWrapped = wrapped.dequeueOutputBuffer()
// Do what you want with resultFromWrapped and return it modified
}
@Override
String getName() {
return wrapped.getName();
}
@Override
void queueInputBuffer(I inputBuffer) throws E {
wrapped.queueInputBuffer(inputBuffer);
}
// Delegate all other methods
};
return wrapper
}
}