boolean result = CodecDescriptionList.isEncodeSupportedByMime(Format.AUDIO_FLAC);
調用 CodecDescriptionList 類的靜態 isDecoderSupportedByFormat/isEncoderSupportedByFormat 方法,判斷某設備是否支持指定 Format 的編解碼器,支持返回 true,否則返回 false。代碼示例如下:
Format format = new Format();format.putStringValue(Format.MIME, Format.VIDEO_AVC); format.putIntValue(Format.WIDTH, 2560); format.putIntValue(Format.HEIGHT, 1440); format.putIntValue(Format.FRAME_RATE, 30); format.putIntValue(Format.FRAME_INTERVAL, 1); boolean result = CodecDescriptionList.isDecoderSupportedByFormat(format); result = CodecDescriptionList.isEncoderSupportedByFormat(format);
三、視頻編解碼
① 視頻編解碼 API
視頻編解碼類 Codec 的主要接口:
接口名功能描述
createDecoder()
創建解碼器Codec實例
createEncoder()
創建編碼器Codec實例
registerCodecListener(ICodecListener listener)
注冊偵聽器用來異步接收編碼或解碼后的數據
setSource(Source source, TrackInfo trackInfo)
根據解碼器的源軌道信息設置數據源,對于編碼器trackInfo無效
setSourceFormat(Format format)
編碼器的管道模式下,設置編碼器編碼格式
setCodecFormat(Format format)
普通模式設置編/解碼器參數
setVideoSurface(Surface surface)
設置解碼器的Surface
getAvailableBuffer(long timeout)
普通模式獲取可用ByteBuffer。
writeBuffer(ByteBuffer buffer, BufferInfo info)
推送源數據給Codec
getBufferFormat(ByteBuffer buffer)
獲取輸出Buffer數據格式
start()
啟動編/解碼
stop()
停止編/解碼
release()
釋放所有資源
② 普通模式
在普通模式下進行編解碼,應用必須持續地傳輸數據到 Codec 實例。
編碼的具體步驟如下:
創建編碼 Codec 實例,可調用 createEncoder() 創建。
final Codec encoder = Codec.createEncoder();
構造數據源格式,并設置給 Codec 實例,調用 setCodecFormat(),代碼示例如下:
Format fmt = new Format();fmt.putStringValue(Format.MIME, Format.VIDEO_AVC);fmt.putIntValue(Format.WIDTH, 1920);fmt.putIntValue(Format.HEIGHT, 1080);fmt.putIntValue(Format.BIT_RATE, 392000);fmt.putIntValue(Format.FRAME_RATE, 30);fmt.putIntValue(Format.FRAME_INTERVAL, 30); codec.setCodecFormat(fmt);
Codec.ICodecListener listener = new Codec.ICodecListener() {@Overridepublic void onReadBuffer(ByteBuffer byteBuffer, BufferInfo bufferInfo, int trackId) {Format fmt = codec.getBufferFormat(byteBuffer);}@Overridepublic void onError(int errorCode, int act, int trackId) {throw new RuntimeException();}};
調用 start() 方法開始解碼。
調用 stop() 方法停止解碼。
解碼任務結束后,調用 release() 釋放資源。
四、視頻播放
① 視頻播放 API
視頻播放包括播放控制、播放設置和播放查詢,如播放的開始/停止、播放速度設置和是否循環播放等。
視頻播放類 Player 的主要接口:
接口名功能描述
Player(Context context)
創建Player實例
setSource(Source source)
設置媒體源
prepare()
準備播放
play()
開始播放
pause()
暫停播放
stop()
停止播放
rewindTo(long microseconds)
拖拽播放
setVolume(float volume)
調節播放音量
setVideoSurface(Surface surface)
設置視頻播放的窗口
enableSingleLooping(boolean looping)
設置為單曲循環
isSingleLooping()
檢查是否單曲循環播放
isNowPlaying()
檢查是否播放
getCurrentTime()
獲取當前播放位置
getDuration()
獲取媒體文件總時長
getVideoWidth()
獲取視頻寬度
getVideoHeight()
獲取視頻高度
setPlaybackSpeed(float speed)
設置播放速度
getPlaybackSpeed()
獲取播放速度
setAudioStreamType(int type)
設置音頻類型
getAudioStreamType()
獲取音頻類型
setNextPlayer(Player next)
設置當前播放結束后的下一個播放器
reset()
重置播放器
release()
釋放播放資源
setPlayerCallback(IPlayerCallback callback)
注冊回調,接收播放器的事件通知或異常通知
② 視頻播放流程
創建 Player 實例,可調用 Player(Context context),創建本地播放器,用于在本設備播放。
構造數據源對象,并調用 Player 實例的 setSource(Source source) 方法,設置媒體源,代碼示例如下:
Player player = new Player(context);File file = new File("/sdcard/test_audio.mp4"); // 根據實際情況設置文件路徑FileInputStream in = new FileInputStream(file);FileDescriptor fd = in.getFD(); // 從輸入流獲取FD對象Source source = new Source(fd);player.setSource(source);
調用 prepare(),準備播放。
(可選)構造 IPlayerCallback,IPlayerCallback 需要實現 onPlayBackComplete 和 onError(int errorType, int errorCode) 兩個方法,實現播放完成和播放異常時做相應的操作。代碼示例如下:
Recorder recorder = new Recorder();Source source = new Source();source.setRecorderAudioSource(Recorder.AudioSource.DEFAULT);recorder.setSource(source);
final int AUDIO_NUM_CHANNELS_STEREO = 2;final int AUDIO_SAMPLE_RATE_HZ = 8000;AudioProperty audioProperty = new AudioProperty.Builder().setRecorderNumChannels(AUDIO_NUM_CHANNELS_STEREO).setRecorderSamplingRate(AUDIO_SAMPLE_RATE_HZ).setRecorderAudioEncoder(Recorder.AudioEncoder.DEFAULT).build();recorder.setAudioProperty(audioProperty);
VideoProperty videoProperty = new VideoProperty.Builder().setRecorderVideoEncoder(Recorder.VideoEncoder.DEFAULT).setRecorderWidth(1080).setRecorderDegrees(0).setRecorderHeight(800).setRecorderBitRate(10000000).setRecorderRate(30).build();recorder.setVideoProperty(videoProperty);
調用 prepare(),準備錄制。
(可選)構造錄制回調,首先構造對象 IRecorderListener,IRecorderListener 需要實現 onError(int what, int extra),實現錄制過程收到錯誤信息時做相應的操作。下面的代碼例子中錄制異常時,打印了相關的日志信息,代碼示例如下:
class RecorderErrorAndInfoListener implements IRecorderListener {@Overridepublic void onError(int what, int extra) {}@Overridepublic void onMessage(int what, int extra) {}}IRecorderListener listener = new RecorderErrorAndInfoListener() {@Overridepublic void onError(int what, int extra) {HiLog.error(TAG, "EncodeWriteFileListener onError what:%{public}d, extra:%{public}d", what, extra);}}
Extractor extractor = new Extractor();File file = new File("/sdcard/test_audio.mp4"); // 根據實際情況設置文件路徑FileInputStream in = new FileInputStream(file);FileDescriptor fd = in.getFD();Source source = new Source(fd);extractor.setSource(source);
調用 getTotalStreams() 方法獲取媒體的軌道數量。
調用 selectStream(int id) 方法選擇特定軌道的數據,進行提取。
(可選)調用 unselectStream(int id) 方法取消選擇軌道。
(可選)調用 rewindTo(long microseconds, int mode) 方法實現提取過程中的跳轉指定位置。
調用 readBuffer(ByteBuffer buf, int offset) 方法,可以實現獲取提取出來的 Buffer 數據功能。
AVDescription avDescription = new AVDescription.Builder().setExtras(null).setMediaId("1").setDescription("Description").setIconUri(iconUri).setIMediaUri(mediaUri).setExtras(pacMap).setIcon(pixelMap).setTitle("title").setSubTitle("subTitle").build();