[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
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose