Android Процесс прямой трансляции : Коллекция видео с мобильного телефона / аудиоданные , Использование видеоданных H.264 кодирование , аудиоданныеиспользовать AAC кодирование , Наконец, аудио и видео данные упаковываются в RTMP в пакете данных , использовать RTMP Соглашение загружено в RTMP на сервере ;
Android Терминал в основном выполняет операцию сбора видеоданных на мобильном терминале. , и передать видеоданные в JNI ,существовать NDK серединаиспользовать x264 Преобразовать изображение в H.264 форматировать видео, Наконец-то будет H.264 форматировать видео Упаковано в RTMP в пакете данных , загрузить в RTMP на сервере ;
В этом блоге представлен следующий контент , Java общий слой Camera собранный NV21 Отформатированные данные передаются в JNI слой , существовать JNI серединаиспользовать x264 кодированиеустройство Воля NV21 изображениеданныекодированиедля H.264 видеоданные ;
Основные пакеты в этом блоге AVC Данные заголовка последовательности , Воля Тип рамы , AVC тип данных , время синтеза , Информация о версии ,кодирование Спецификация, NALU длина , SPS число , SPS длина , SPS данные , PPS число , PPS длина , PPS данные , инкапсулированный в RTMP В сумке ;
1 . Этополныйвидео Этикеткаданные内容 : Это FLV середина完整видео Этикеткаданные ;
0x00000182 : 09 00 00 2E 00 00 00 00
0x0000018a : 00 00 00 17 00 00 00 00
0x00000192 : 01 64 00 32 FF E1 00 19
0x0000019a : 67 64 00 32 AC D9 80 78
0x000001a2 : 02 27 E5 84 00 00 03 00
0x000001aa : 04 00 00 1F 40 3C 60 C6
0x000001b2 : 68 01 00 05 68 E9 7B 2C
0x000001ba : 8B 00 00 00 39
2 . Заголовок тега : вперед
индивидуальныйbyteда Заголовок тегаданные , Хранится с Тип тега ,Этикеткаданныеразмер, Временная метка , Временная удлинитель метка , номер потока ждать
Байтовая информация;
0x00000182 : 09 00 00 2E 00 00 00 00
0x0000018a : 00 00 00
3 . Этикеткаданные ( фокус ) : Это то, что этот блог собирается инкапсулировать , По сути, он инкапсулирует формат,который точно такой же. RTMP данные Сумка,
17 00 00 00 00
0x00000192 : 01 64 00 32 FF E1 00 19
0x0000019a : 67 64 00 32 AC D9 80 78
0x000001a2 : 02 27 E5 84 00 00 03 00
0x000001aa : 04 00 00 1F 40 3C 60 C6
0x000001b2 : 68 01 00 05 68 E9 7B 2C
0x000001ba : 8B 00 00 00 39
Справочный блог : Ссылка на две статьи форварданализировать RTMP Блог в формате данных ,проанализировал RTMP Формат почти тот же FLV видеоданные Формат ;
Эти два блога должны быть , и понять FLV видео Этикеткаданные Формат , Только тогда я смогу понять,что я написал сегодня. RTMP данные Сумка Инкапсуляциясодержание ;
1 . данные Пример :
17 00 00 00 00
0x00000192 : 01 64 00 32 FF E1 00 19
0x0000019a : 67 64 00 32 AC D9 80 78
0x000001a2 : 02 27 E5 84 00 00 03 00
0x000001aa : 04 00 00 1F 40 3C 60 C6
0x000001b2 : 68 01 00 05 68 E9 7B 2C
0x000001ba : 8B 00 00 00 39
На сегодняшний день это место имеет 13 байтданные
67 64 00 32 AC D9 80 78
0x000001a2 : 02 27 E5 84 00 00 03 00
0x000001aa : 04 00 00 1F 40 3C 60 C6
0x000001b2 : 68
68 E9 7B 2C
0x000001ba : 8B
2 . Рассчитайте весь SPS и PPS данныеизразмер :
① Заголовок пакета : Тип рамы , тип данных , время синтеза , Информация о версии ,кодированиеправило, NALU длина , Есть всего
байт;
② Инкапсуляция SPS данные : SPS число , SPS длина , SPS данные , соответственно
байт;
③ Инкапсуляция PPS данные : PPS число , PPS длина , PPS данные , соответственно
байт;
int rtmpPackagesize = 10 + 3 + spsLen + 3 + ppsLen;
К RTMP в пакете данных , Инкапсуляция Тип рамы , тип данных , время синтеза , Информация о версии ,кодированиеправило, NALU длина , Есть всего
байт;
// Тип рамыданные : Разделен на две части;
// вперед 4 Бит означает Тип рамы, 1 представляет ключевые кадры, 2 Представляет собой обычный кадр
// назад 4 Бит представляет тип кодирования, 7 выражать AVC видеокодирование
rtmpPacket->m_body[nextPosition++] = 0x17;
// тип данных, 00 выражать AVC заголовок последовательности
rtmpPacket->m_body[nextPosition++] = 0x00;
// время синтеза, 一般настраивать 00 00 00
rtmpPacket->m_body[nextPosition++] = 0x00;
rtmpPacket->m_body[nextPosition++] = 0x00;
rtmpPacket->m_body[nextPosition++] = 0x00;
// Информация о версии
rtmpPacket->m_body[nextPosition++] = 0x01;
//кодирование Спецификация rtmpPacket->m_body[nextPosition++] = sps[1];
rtmpPacket->m_body[nextPosition++] = sps[2];
rtmpPacket->m_body[nextPosition++] = sps[3];
// NALU длина
rtmpPacket->m_body[nextPosition++] = 0xFF;
Воля SPS данныеинкапсулированный в RTMP в пакете данных , Включать SPS число , SPS длина , SPS данные ;
// SPS число
rtmpPacket->m_body[nextPosition++] = 0xE1;
// SPS длина, занимать 2 байт
// настраиватьдлинавысокое положение rtmpPacket->m_body[nextPosition++] = (spsLen >> 8) & 0xFF;
// настраиватьдлинанизкая позиция rtmpPacket->m_body[nextPosition++] = spsLen & 0xFF;
// копировать SPS данные
// Воля SPS данныекопироватьприезжать rtmpPacket->m_body[nextPosition] по адресу
memcpy(&rtmpPacket->m_body[nextPosition], sps, spsLen);
// Накапливать SPS длинаинформация nextPosition += spsLen;
Воля PPS данныеинкапсулированный в RTMP в пакете данных , Включать PPS число , PPS длина , PPS данные ;
// PPS число
rtmpPacket->m_body[nextPosition++] = 0x01;
// PPS данныеиздлина, занимать 2 байт
// настраиватьдлинавысокое положение rtmpPacket->m_body[nextPosition++] = (ppsLen >> 8) & 0xFF;
// настраиватьдлинанизкая позиция rtmpPacket->m_body[nextPosition++] = (ppsLen) & 0xFF;
// копировать SPS данные
memcpy(&rtmpPacket->m_body[nextPosition], pps, ppsLen);
настраивать RTMP тип упаковки ,RTMP Сумкадлина, RTMP ряд ,Временная метка ждатьинформация ;
// настраивать RTMP тип упаковки, видеотипданные rtmpPacket->m_packetType = RTMP_PACKET_TYPE_VIDEO;
// настраиватьRTMP Сумкадлина rtmpPacket->m_nBodySize = rtmpPackagesize;
// распространять RTMP ряд, случайныйраспространять
rtmpPacket->m_nChannel = 10;
// настраиватьвидео Временная метка, в случае SPP PPS данные, Нет Временная метка
rtmpPacket->m_nTimeStamp = 0;
// настройка абсолютного времени, для SPS PPS Назначение 0 Вот и все
rtmpPacket->m_hasAbsTimestamp = 0;
// настройки типа головы, Не стесняйтесь настраивать один
rtmpPacket->m_headerType = RTMP_PACKET_SIZE_MEDIUM;
/**
* Воля SPS / PPS данные Отправить RTMP серверная часть
* @param sps SPS данные
* @param pps PPS данные
* @param spsLen SPS длина
* @param ppsLen PPS длина
*/
void VedioChannel::sendSpsPpsToRtmpServer(uint8_t *sps, uint8_t *pps, int spsLen, int ppsLen) {
// создавать RTMP данные Сумка, Воляданные все откладываются в этом RTMP в пакете данных
RTMPPacket *rtmpPacket = new RTMPPacket;
/*
Рассчитайте весь SPS и PPS данныеизразмер данные Пример :
17 00 00 00 00
0x00000192 : 01 64 00 32 FF E1 00 19
0x0000019a : 67 64 00 32 AC D9 80 78
0x000001a2 : 02 27 E5 84 00 00 03 00
0x000001aa : 04 00 00 1F 40 3C 60 C6
0x000001b2 : 68 01 00 05 68 E9 7B 2C
0x000001ba : 8B 00 00 00 39
17 Тип рамы, 1 байт
00 тип данных, 1 байт
00 00 00 время синтеза, 3 байт
01 Информация о версии,1 байт
64 00 32 кодированиеправило, 3 байт
FF NALU длина, 1 байт
E1 SPS число, 1 байт
00 19 SPS длина, 2 байт
На сегодняшний день это место имеет 13 байтданные
spsLen байтданные, вот 25 байт
67 64 00 32 AC D9 80 78
0x000001a2 : 02 27 E5 84 00 00 03 00
0x000001aa : 04 00 00 1F 40 3C 60 C6
0x000001b2 : 68
01 PPS число, 1 байт
00 05 PPS длина, 2 байт
ppsLen байтиз PPS данные
68 E9 7B 2C
0x000001ba : 8B
позади 00 00 00 39 давидео Этикеткаобщего количествадлина
Здесь снова RTMP Инкапсуляция не требуется в Этикетике.
*/
int rtmpPackagesize = 10 + 3 + spsLen + 3 + ppsLen;
// для RTMP данные Сумкараспространять内存
RTMPPacket_Alloc(rtmpPacket, rtmpPackagesize);
// Запишите следующую позицию индекса для записи в данные.
int nextPosition = 0;
// Тип рамыданные : Разделен на две части;
// вперед 4 Бит означает Тип рамы, 1 представляет ключевые кадры, 2 Представляет собой обычный кадр
// назад 4 Бит представляет тип кодирования, 7 выражать AVC видеокодирование
rtmpPacket->m_body[nextPosition++] = 0x17;
// тип данных, 00 выражать AVC заголовок последовательности
rtmpPacket->m_body[nextPosition++] = 0x00;
// время синтеза, 一般настраивать 00 00 00
rtmpPacket->m_body[nextPosition++] = 0x00;
rtmpPacket->m_body[nextPosition++] = 0x00;
rtmpPacket->m_body[nextPosition++] = 0x00;
// Информация о версии
rtmpPacket->m_body[nextPosition++] = 0x01;
//кодирование Спецификация rtmpPacket->m_body[nextPosition++] = sps[1];
rtmpPacket->m_body[nextPosition++] = sps[2];
rtmpPacket->m_body[nextPosition++] = sps[3];
// NALU длина
rtmpPacket->m_body[nextPosition++] = 0xFF;
// SPS число
rtmpPacket->m_body[nextPosition++] = 0xE1;
// SPS длина, занимать 2 байт
// настраиватьдлинавысокое положение rtmpPacket->m_body[nextPosition++] = (spsLen >> 8) & 0xFF;
// настраиватьдлинанизкая позиция rtmpPacket->m_body[nextPosition++] = spsLen & 0xFF;
// копировать SPS данные
// Воля SPS данныекопироватьприезжать rtmpPacket->m_body[nextPosition] по адресу
memcpy(&rtmpPacket->m_body[nextPosition], sps, spsLen);
// Накапливать SPS длинаинформация nextPosition += spsLen;
// PPS число
rtmpPacket->m_body[nextPosition++] = 0x01;
// PPS данныеиздлина, занимать 2 байт
// настраиватьдлинавысокое положение rtmpPacket->m_body[nextPosition++] = (ppsLen >> 8) & 0xFF;
// настраиватьдлинанизкая позиция rtmpPacket->m_body[nextPosition++] = (ppsLen) & 0xFF;
// копировать SPS данные
memcpy(&rtmpPacket->m_body[nextPosition], pps, ppsLen);
// настраивать RTMP тип упаковки, видеотипданные rtmpPacket->m_packetType = RTMP_PACKET_TYPE_VIDEO;
// настраиватьRTMP Сумкадлина rtmpPacket->m_nBodySize = rtmpPackagesize;
// распространять RTMP ряд, случайныйраспространять
rtmpPacket->m_nChannel = 10;
// настраиватьвидео Временная метка, в случае SPP PPS данные, Нет Временная метка
rtmpPacket->m_nTimeStamp = 0;
// настройка абсолютного времени, для SPS PPS Назначение 0 Вот и все
rtmpPacket->m_hasAbsTimestamp = 0;
// настройки типа головы, Не стесняйтесь настраивать один
rtmpPacket->m_headerType = RTMP_PACKET_SIZE_MEDIUM;
}