68
Android: низкоуровневые мультимедиа API И их применение в реальной жизни Григорий Клюшников Android-разработчик ВКонтакте vk.com/grishka Telegram: @grishka

Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Embed Size (px)

Citation preview

Page 1: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Android: низкоуровневые мультимедиа API

И их применение в реальной жизни

Григорий Клюшников Android-разработчик ВКонтакте vk.com/grishka Telegram: @grishka

Page 2: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Как это работает: медиаплеер(простой случай: локальный аудиофайл)

Файл Парсер Кодек

Page 3: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Как это работает: медиаплеер(случай сложнее: локальное видео)

Файл Парсер

Кодек

Кодек

Page 4: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Как это работает: медиаплеер(потоковое видео)

Буфер Парсер

Кодек

Кодек

Page 5: Android: низкоуровневые мультимедиа API и их применение в реальной жизни
Page 6: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

android.media.MediaPlayer

Page 7: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

MediaPlayer player = new MediaPlayer(); player.setDataSource("http://example.com/song.mp3"); player.prepare(); // blocking player.start(); // Не забудьте освободить ресурсы!

Page 8: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: кэш

Буфер Парсер Кодек

Page 9: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: кэш

Буфер Парсер Кодек

Page 10: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: кэш

Буфер Парсер Кодек

Page 11: Android: низкоуровневые мультимедиа API и их применение в реальной жизни
Page 12: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: кэш

Буфер Парсер Кодек

Page 13: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: кэш

Буфер Парсер Кодек

HTTP-прокси

Page 14: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: кэш

Буфер Парсер Кодек

HTTP-прокси Файл

Page 15: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: кэш

https://psv4.vk.me/c422431/u67616085/audios/37c79c8bdcd…

http://127.0.0.1:5483/?https%3A%2F%2Fpsv4.vk.me%2Fc4224…

Page 16: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: сеть

LTE

Page 17: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: сеть

LTE

Page 18: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: сеть

LTE

Page 19: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: сеть

3G

Page 20: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: сеть

E

Page 21: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: сеть

E

Page 22: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: сеть

E

Page 23: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: сеть

Page 24: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: сеть

При воспроизведении произошла ошибка

Page 25: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Суровая реальность: сеть

LTE

Page 26: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

ExoPlayer

Page 27: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

ExoPlayer

Page 28: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

ExoPlayer

MediaPlayer

Логика плеера

Сеть Буферизация Разделение Распаковка Вывод

Page 29: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

ExoPlayer

MediaExtractor

Сеть Буферизация Разделение Распаковка Вывод

Логика плеера

MediaCodec AudioTrack

Плеер уровня приложения

Page 30: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

ExoPlayer

Page 31: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

ExoPlayer

E

Page 32: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

ExoPlayer

E

Page 33: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

DIY

Своя реализация

Сеть Буферизация Разделение

Распаковка Вывод

Логика плеера

MediaCodec AudioTrack

Плеер уровня приложения

Page 34: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Буферизация и кэширование одновременно: почему бы и нет?

1708231_352255247.part

Page 35: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Буферизация и кэширование одновременно: почему бы и нет?

1708231_352255247.part

ID3

Page 36: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Буферизация и кэширование одновременно: почему бы и нет?

1708231_352255247.part

ID3

Page 37: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Буферизация и кэширование одновременно: почему бы и нет?

1708231_352255247.part

ID3 Сжатые данные (в виде фреймов)

Page 38: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Буферизация и кэширование одновременно: почему бы и нет?

Page 39: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Буферизация и кэширование одновременно: почему бы и нет?• OkHttp

Page 40: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Буферизация и кэширование одновременно: почему бы и нет?• OkHttp

• Докачка

Page 41: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Буферизация и кэширование одновременно: почему бы и нет?• OkHttp

• Докачка

• Предсказуемая буферизация

Page 42: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Буферизация и кэширование одновременно: почему бы и нет?• OkHttp

• Докачка

• Предсказуемая буферизация

• Переполучение ссылок при смене IP

Page 43: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Буферизация и кэширование одновременно: почему бы и нет?• OkHttp

• Докачка

• Предсказуемая буферизация

• Переполучение ссылок при смене IP

• Отлично работает в метро (я проверял)

Page 44: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

MediaCodec codec = MediaCodec.createDecoderByType("audio/mpeg"); MediaFormat format = MediaFormat.createAudioFormat("audio/mpeg", sampleRate, isMono ? 1 : 2); MediaCodec.BufferInfo info=new MediaCodec.BufferInfo(); codec.configure(format, null, null, 0); codec.start(); ByteBuffer[] in=codec.getInputBuffers(); ByteBuffer[] out=codec.getOutputBuffers(); !AudioTrack track=new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, isMono ? AudioFormat.CHANNEL_OUT_MONO : AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, 10240*4, AudioTrack.MODE_STREAM); track.play();

Page 45: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

while (!endOfStream) { int inIndex = codec.dequeueInputBuffer(-1); if (inIndex >= 0) { in[inIndex].clear(); in[inIndex].position(0); in[inIndex].put(frameData, 0, frameSize); codec.queueInputBuffer(inIndex, 0, frameSize, sampleTime, 0); } int outIndex = codec.dequeueOutputBuffer(info, 1000); if (outIndex >= 0) { out[outIndex].position(info.offset); out[outIndex].get(codecBuffer, 0, info.size); track.write(codecBuffer, 0, info.size); codec.releaseOutputBuffer(outIndex, false); } }

Page 46: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Видео

Page 47: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Видео(всё очень плохо)

Page 48: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Видео(всё очень плохо)

(раньше было ещё хуже)

Page 49: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Приложение AskVideoAnswer

Page 50: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Приложение AskVideoAnswer• Использует

недокументированное API Ask.fm

Page 51: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Приложение AskVideoAnswer• Использует

недокументированное API Ask.fm

• Сжимает видео перед отправкой

Page 52: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Приложение AskVideoAnswer• Использует

недокументированное API Ask.fm

• Сжимает видео перед отправкой

• Сделано в стиле Material Design

Page 53: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Приложение AskVideoAnswer• Использует

недокументированное API Ask.fm

• Сжимает видео перед отправкой

• Сделано в стиле Material Design

• Позволяет доминировать над пользователями iOS

Page 54: Android: низкоуровневые мультимедиа API и их применение в реальной жизни
Page 55: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Что такое видеофайл?З

агол

овок

Page 56: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

AVI = Audio/Video Interleaved(но мы будем говорить про mp4)

Page 57: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

MediaExtractor

MediaMuxer

Page 58: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

4.3+API level 18

Page 59: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Файл MediaExtractor

MediaCodec decoder

MediaCodec decoder

Уменьшение размера кадра

MediaCodec encoder

MediaCodec encoder

ФайлMediaMuxer

Page 60: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Цветовое пространство YUV

Page 61: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Цветовое пространство YUV

Page 62: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Цветовое пространство YUV

Y U V

Page 63: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Уменьшаем кадры правильно

Page 64: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

private static void resizeYuvFrame(byte[] from, byte[] to, int w, int h, int sample){ int tw = w / sample; int th = h / sample; // Y for(int y = 0; y < th; y++) { for(int x = 0; x < tw; x++) { to[y*tw+x] = from[y * sample * w + x * sample]; } } // UV int offset = tw * th; for(int y = 0; y < th / 2; y++) { for(int x = 0; x < tw / 2; x++) { int uIndex = y * sample * w + x * sample * 2; to[offset] = from[w * h + uIndex]; // u to[offset + 1] = from[w * h + uIndex + 1]; // v offset += 2; } } }

Page 65: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Фрагментация

Кадр здорового человекаКадр курильщика

Qualcomm

Page 66: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

/* get frame tile coordinate. XXX: nothing to be understood here, don't try. */

— исходный код VLC

Page 67: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Приложение-пример

Page 68: Android: низкоуровневые мультимедиа API и их применение в реальной жизни

Q & AСсылка на приложение-пример на GitHub

Григорий Клюшников vk.com/grishka Telegram: @grishka