[Android RTMP] Процесс push-уведомления RTMPDump (отправка независимого потока | создание pusher | операция инициализации | установка push-адреса | включение записи | подключение к RTMP-серверу | отправка RTMP-пакетов)
[Android RTMP] Процесс push-уведомления RTMPDump (отправка независимого потока | создание pusher | операция инициализации | установка push-адреса | включение записи | подключение к RTMP-серверу | отправка RTMP-пакетов)

Каталог статей

1. Обработка push-адреса RTMP, переданного с уровня Java.


1 . Java Передать строковые данные в JNI : При запуске push-стриминга , Java слой будет RTMP Адрес push передается JNI ;

2 . jstring Преобразование типа в char* тип : Воля Java Преобразовать строку в C нить ;

Язык кода:javascript
копировать
// получать Rtmp Отправить адрес потока
// Должен pushPathFromJava Ссылка — это локальная ссылка, Оно будет недействительным, если оно выходит за рамки.
// Локальные ссылки не могут охватывать метод , Звонок через нить
const char* pushPathFromJava = env->GetStringUTFChars(path, 0);

3 . Обработка локальной ссылочной переменной : Преобразованный const char* pushPathFromJava нить — локальная ссылочная переменная , Невозможно пересекать процессы , Использование в разных областях , Последующие операции push используются в отдельных потоках. , Поэтому Волянить данные существования необходимо хранить в куче памяти. ;

Язык кода:javascript
копировать
// получатьадресдлина, плюс '\0' длина
char * pushPathNative = new char[strlen(pushPathFromJava) + 1];
// копировать pushPathFromJava перегружать память pushPathNative середина
// Локальные ссылки не могут охватывать метод , Звонок через нить, Здесь вам нужно существоватьсередина, используя адрес Должена.
// Поэтому необходимо Воля Долженместная ссылкакопироватьперегружать памятьсередина, Затем передали соответствующему нитьсередина.
strcpy(pushPathNative, pushPathFromJava);

4 . Освободить локальную ссылку : JNI локальные ссылочные переменные в , Отпустите сразу после использования ;

Язык кода:javascript
копировать
// освобождение от Java слойполучатьизнить
// Освободить локальную ссылку
env->ReleaseStringUTFChars(path, pushPathFromJava);

2. Потоковый поток RTMPDump


1 . Независимый толчок нити : RTMP Операцию push необходимо выполнить в отдельном потоке. , Операции, связанные с сетью, требуют много времени. , существовать Android середина Необходимыйсуществоватьнитьсерединаосуществлять ;

2 . нить ID заявление : Нужно импортировать #include <pthread.h> Сумка , Только тогда ты сможешь использовать нить ,Первыйзаявлениенить ID, pthread_t тип ;

Язык кода:javascript
копировать
/**
 * Начать продвигать поток работы нить нить ID
 */
pthread_t startRtmpPushPid;

3 . создаватьиосуществлятьнить : создаватьиосуществлятьнить , существоватьнитьсерединаосуществлять startRtmpPush метод ,входящий pushPathNative нитьпараметр ;

Язык кода:javascript
копировать
// создаватьнить
pthread_create(&startRtmpPushPid, 0, startRtmpPush, pushPathNative);

4 . нитьметод : Определение нитметод , И параметры, и возвращаемые значения void* тип , существоватьстартовая позицияполучатьвходящийизпараметр ;

Язык кода:javascript
копировать
void* startRtmpPush (void* args){
    // 0. получать Rtmp Отправить адрес потока
    char* pushPath = static_cast<char *>(args);
	// ...
}

3. Создайте объект RTMP.


создавать RTMP объект , Если создатель потерпит неудачу , Просто остановите весь метод push-потока ;

Язык кода:javascript
копировать
// 1. создавать RTMP объект, Подать заявку на память
rtmp = RTMP_Alloc();
if (!rtmp) {
    __android_log_print(ANDROID_LOG_INFO, "RTMP", "Применять RTMP Память подвела");
    break;
}

4. Инициализируйте объект RTMP.


инициализация RTMP объект , и установите тайм-аут ;

Язык кода:javascript
копировать
// 2. инициализация RTMP
RTMP_Init(rtmp);
// настройка таймаута 5 Второй
rtmp->Link.timeout = 5;

5. Установите адрес потоковой передачи RTMP.


Установите адрес push-уведомления RTMP. Если настройка не удалась, выйдите из операции push напрямую;

Адрес Java слой передан в JNI изнить, Это локальная ссылочная переменная, когда она впервые получена. , Воляитскопировать в кучу памятисередина , Только тогда можносуществоватьтолкатьпотокнитьсерединаиспользовать ;

Язык кода:javascript
копировать
// 3. настраивать RTMP Отправить адрес потокового сервера
int ret = RTMP_SetupURL(rtmp, pushPath);
if (!ret) {
    __android_log_print(ANDROID_LOG_INFO, "RTMP", "настраивать RTMP Отправить адрес потокового сервера %s неудача", pushPath);
    break;
}

6. Включите функцию записи RTMP.


Включить запись RTMP;

Язык кода:javascript
копировать
// 4. давать возможность RTMP функция записи
RTMP_EnableWrite(rtmp);

7. Подключитесь к RTMP-серверу.


соединять RTMP сервер , Если соединение не удалось , прямойпокидать Долженметод ;

Язык кода:javascript
копировать
// 5. соединять RTMP сервер
ret = RTMP_Connect(rtmp, 0);
if (!ret) {
    __android_log_print(ANDROID_LOG_INFO, "RTMP", "соединять RTMP сервер %s неудача", pushPath);
    break;
}

8. Подключитесь к потоку RTMP.


соединять RTMP поток , Если соединение не удалось ,покидатьметод ;

Язык кода:javascript
копировать
// 6. соединять RTMP поток
ret = RTMP_ConnectStream(rtmp, 0);
if (!ret) {
    __android_log_print(ANDROID_LOG_INFO, "RTMP", "соединять RTMP поток %s неудача", pushPath);
    break;
}

9. Отправка RTMP-пакетов


Воля RTMP данные Сумкаотправлятьприезжатьсерверсередина ;

Язык кода:javascript
копировать
// 7. Воля RTMP данные Сумкаотправлятьприезжатьсерверсередина
ret = RTMP_SendPacket(rtmp, packet, 1);

10. Отключите RTMP-соединение и освободите ресурсы.


толкатьпоток После окончания , близко с RTMP серверсоединять , Освободить ресурсы ;

Язык кода:javascript
копировать
// 8. Нажмите поток, чтобы закончить, близко с RTMP серверсоединять, Освободить ресурсы
if(rtmp){
    RTMP_Close(rtmp);
    RTMP_Free(rtmp);
}

11. Push-код RTMPDump


RTMPDump отправить код потока :

Язык кода:javascript
копировать
/**
 * Запустить удаленно RTMP серверPush data
 */
extern "C"
JNIEXPORT void JNICALL
Java_kim_hsl_rtmp_LivePusher_native_1startRtmpPush(JNIEnv *env, jobject thiz,
                                                                jstring path) {
    if(isStartRtmpPush){
        // Предотвратить многократный вызов Долженметода, Если он был вызван ранее, Тогда заблокируйте этот звонок
        return;
    }
    // Выполнив его один раз, Немедленно отметьте выполненный статус, Не в следующий разосуществлять Долженметод Понятно
    isStartRtmpPush = TRUE;

    // получать Rtmp Отправить адрес потока
    // Должен pushPathFromJava Ссылка — это локальная ссылка, Оно будет недействительным, если оно выходит за рамки.
    // Локальные ссылки не могут охватывать метод , Звонок через нить
    const char* pushPathFromJava = env->GetStringUTFChars(path, 0);

    // получатьадресдлина, плюс '\0' длина
    char * pushPathNative = new char[strlen(pushPathFromJava) + 1];
    // копировать pushPathFromJava перегружать память pushPathNative середина
    // Локальные ссылки не могут охватывать метод , Звонок через нить, Здесь вам нужно существоватьсередина, используя адрес Должена.
    // Поэтому необходимо Воля Долженместная ссылкакопироватьперегружать памятьсередина, Затем передали соответствующему нитьсередина.
    strcpy(pushPathNative, pushPathFromJava);

    // создаватьнить
    pthread_create(&startRtmpPushPid, 0, startRtmpPush, pushPathNative);

    // освобождение от Java слойполучатьизнить
    // Освободить локальную ссылку
    env->ReleaseStringUTFChars(path, pushPathFromJava);    
}


/**
 * Начни продвигать миссию по потоку нить
 * В основном звоню RTMPDump Сделайте толчок
 * @param args
 * @return
 */
void* startRtmpPush (void* args){
    // 0. получать Rtmp Отправить адрес потока
    char* pushPath = static_cast<char *>(args);

    // rtmp толкатель потока
    RTMP* rtmp = 0;
    // rtmp толкатьпотокданные Сумка    RTMPPacket *packet = 0;

    /*
        Воля подталкивает поток выполнения основного контента, чтобы обеспечить существование do while циклсередина
        существовать После ошибки, в любое время break выйти из цикла, Выполните следующее Освободить код ресурса
        Это может быть гарантировано, существуют Наконец-то ресурсы Воля освобождены, Избегайте утечек памяти
        Избегайте неудачного выполнения, прямой return, В результате ресурсы не освобождаются.
     */
    do {
        // 1. создавать RTMP объект, Подать заявку на память
        rtmp = RTMP_Alloc();
        if (!rtmp) {
            __android_log_print(ANDROID_LOG_INFO, "RTMP", "Применять RTMP Память подвела");
            break;
        }

        // 2. инициализация RTMP
        RTMP_Init(rtmp);
        // настройка таймаута 5 Второй
        rtmp->Link.timeout = 5;

        // 3. настраивать RTMP Отправить адрес потокового сервера
        int ret = RTMP_SetupURL(rtmp, pushPath);
        if (!ret) {
            __android_log_print(ANDROID_LOG_INFO, "RTMP", "настраивать RTMP Отправить адрес потокового сервера %s неудача", pushPath);
            break;
        }
        // 4. давать возможность RTMP функция записи
        RTMP_EnableWrite(rtmp);

        // 5. соединять RTMP сервер
        ret = RTMP_Connect(rtmp, 0);
        if (!ret) {
            __android_log_print(ANDROID_LOG_INFO, "RTMP", "соединять RTMP сервер %s неудача", pushPath);
            break;
        }

        // 6. соединять RTMP поток
        ret = RTMP_ConnectStream(rtmp, 0);
        if (!ret) {
            __android_log_print(ANDROID_LOG_INFO, "RTMP", "соединять RTMP поток %s неудача", pushPath);
            break;
        }

        // Приготовьтесь отправить данные, связанные с потоком, Например, нить очереди безопасности
        readyForPush = TRUE;
        // Запись времени начала push-потока
        pushStartTime = RTMP_GetTime();
        // нитьSecurity Queue начинает работать
        packets.setWork(1);

        while (isStartRtmpPush) {
            // Из нить очереди безопасности середина
            // Достаньте побитую Сумку RTMP данные Сумка            packets.pop(packet);

            // Убедитесь, что вы в данный момент нажимаете поток
            if (!isStartRtmpPush) {
                break;
            }

            // Убедитесь, что пустые не вынуты. RTMP данные Сумка            if (!packet) {
                continue;
            }

            // настраиватьпрямая трансляцияизпоток ID
            packet->m_nInfoField2 = rtmp->m_stream_id;

            // 7. Воля RTMP данные Сумкаотправлятьприезжатьсерверсередина
            ret = RTMP_SendPacket(rtmp, packet, 1);

            // RTMP После использования данных Сумка, выпускать Долженданные Сумка            if (packet) {
                RTMPPacket_Free(packet);
                delete packet;
                packet = 0;
            }

            if (!ret) {
                __android_log_print(ANDROID_LOG_INFO, "RTMP", "RTMP Ошибка отправки потока данных "Сумка данных");
                break;
            }
        }

    }while (0);


    // Поверхностная часть является отделочной частью, Освободить ресурсы


    // 8. Нажмите поток, чтобы закончить, близко с RTMP серверсоединять, Освободить ресурсы
    if(rtmp){
        RTMP_Close(rtmp);
        RTMP_Free(rtmp);
    }

    // толкатьпотокданные Сумка освободить очередь безопасности
    // предотвращатьсерединаспособпокидатьв результате нет Освободить ресурсы, вызывая утечки памяти
    if (packet) {
        RTMPPacket_Free(packet);
        delete packet;
        packet = 0;
    }

    // выпускать Отправить адрес потока
    if(pushPath){
        delete pushPath;
        pushPath = 0;
    }
    return 0;
}
boy illustration
Подробное объяснение механизма подтверждения выпуска сообщений RabbitMQ.
boy illustration
На этот раз полностью поймите протокол ZooKeeper.
boy illustration
Реализуйте загрузку файлов с использованием минимального WEB API.
boy illustration
Демо1 Laravel5.2 — генерация и хранение URL-адресов
boy illustration
Spring boot интегрирует Kafka и реализует отправку и потребление информации (действительно при личном тестировании)
boy illustration
Мысли о решениях по внутренней реализации сортировки методом перетаскивания
boy illustration
Междоменный доступ к конфигурации nginx не может вступить в силу. Междоменный доступ к странице_Page
boy illustration
Как написать текстовый контент на php
boy illustration
PHP добавляет текстовый водяной знак или водяной знак изображения к изображениям – метод инкапсуляции
boy illustration
Интерпретация быстрой таблицы (TLB)
boy illustration
Интерфейс WeChat API (полный) — оплата WeChat/красный конверт WeChat/купон WeChat/магазин WeChat/JSAPI
boy illustration
Преобразование Java-объекта в json string_complex json-строки в объект
boy illustration
Примените сегментацию слов jieba (версия Java) и предоставьте пакет jar
boy illustration
matinal: Самый подробный анализ управления разрешениями во всей сети SAP. Все управление разрешениями находится здесь.
boy illustration
Коротко расскажу обо всем процессе работы алгоритма сборки мусора G1 --- Теоретическая часть -- Часть 1
boy illustration
[Спецификация] Результаты и исключения возврата интерфейса SpringBoot обрабатываются единообразно, поэтому инкапсуляция является элегантной.
boy illustration
Интерпретация каталога веб-проекта Flask
boy illustration
Что такое подробное объяснение файла WSDL_wsdl
boy illustration
Как запустить большую модель ИИ локально
boy illustration
Подведение итогов десяти самых популярных веб-фреймворков для Go
boy illustration
5 рекомендуемых проектов CMS с открытым исходным кодом на базе .Net Core
boy illustration
Java использует httpclient для отправки запросов HttpPost (отправка формы, загрузка файлов и передача данных Json)
boy illustration
Руководство по развертыванию Nginx в Linux (Centos)
boy illustration
Интервью с Alibaba по Java: можно ли использовать @Transactional и @Async вместе?
boy illustration
Облачный шлюз Spring реализует примеры балансировки нагрузки и проверки входа в систему.
boy illustration
Используйте Nginx для решения междоменных проблем
boy illustration
Произошла ошибка, когда сервер веб-сайта установил соединение с базой данных. WordPress предложил решение проблемы с установкой соединения с базой данных... [Легко понять]
boy illustration
Новый адрес java-библиотеки_16 топовых Java-проектов с открытым исходным кодом, достойных вашего внимания! Обязательно к просмотру новичкам
boy illustration
Лучшие практики Kubernetes для устранения несоответствий часовых поясов внутри контейнеров
boy illustration
Введение в проект удаления водяных знаков из коротких видео на GitHub Douyin_TikTok_Download_API