Практика разработки HarmonyOS — воспроизведение видео на базе AVPlayer
Практика разработки HarmonyOS — воспроизведение видео на базе AVPlayer

1 Описание сцены

Пример сценария: реализация AVPlayer в ArkTS для воспроизведения видео, создания AVPlayer, установки ресурсов и окон воспроизведения, установки параметров воспроизведения, управления воспроизведением (воспроизведение/пауза/переход), сброса, уничтожения ресурсов, переключения видео после завершения воспроизведения.

2 Описание решения

AVPlayer: ArkTS API для воспроизведения аудио и видео с относительно полными функциями. Он объединяет функции анализа потокового мультимедиа и локальных ресурсов, декапсуляции медиаресурсов, декодирования видео и рендеринга. Он может напрямую работать. воспроизводить mp4, видео файлы в формате mkv и других форматах. В этом примере представлена ​​реализация воспроизведения видео с помощью avplayer. Функции включают в себя воспроизведение видео несколькими способами и управление воспроизведением видео.

Конкретные шаги реализации можно разделить на Шаг 1: Вызов createAVPlayer() для создания экземпляра AVPlayer. Шаг 2. Установите события прослушивания, необходимые для бизнеса, и используйте их в сценариях полного процесса. Шаг 3. Установка окна. Получите и установите атрибут SurfaceID, который используется для установки экрана дисплея. Приложению необходимо получить идентификатор поверхности из компонента XComponent. В то же время настройку события загрузки следует изменить на и завершить операцию установки ресурса воспроизведения в обратном вызове события загрузки. Шаг 4: Зарегистрируйте функцию обратного вызова avplayer. Шаг 5: Вызовите соответствующий интерфейс для реализации play(), паузы(. ), перейти к поиску() и другим операциям.

2.1 Создайте экземпляр AVPlayer

Вызовите createAVPlayer(), чтобы создать экземпляр AVPlayer.

1. Установите сетевой адрес через URL-адрес для воспроизведения. Адрес сетевого видео:

Язык кода:ts
копировать
https://sns-video-bd.xhscdn.com/stream/110/258/01e602cadc11542d010370038e7ae8b418_258.mp4

async avPlayerLiveDemo() {
  // Создать объект экземпляра avPlayer
  let avPlayer: media.AVPlayer = await media.createAVPlayer();
  // Создайте функцию обратного вызова изменения конечного автомата
  this.setAVPlayerCallback(avPlayer);
  avPlayer.url = 'https://sns-video-bd.xhscdn.com/stream/110/258/01e602cadc11542d010370038e7ae8b418_258.mp4'; // Воспроизвести онлайн-видео
}
}

2. Используйте файловую систему fs, чтобы открыть адрес песочницы, получить адрес медиафайла и воспроизвести его с помощью атрибута dataSrc.

Язык кода:ts
копировать
async avPlayerLiveDemo() {
  // Создать объект экземпляра avPlayer
  let avPlayer: media.AVPlayer = await media.createAVPlayer();
  // Создайте функцию обратного вызова изменения конечного автомата
  this.setAVPlayerCallback(avPlayer);
  avPlayer.url = 'https://sns-video-bd.xhscdn.com/stream/110/258/01e602cadc11542d010370038e7ae8b418_258.mp4'; // Воспроизвести онлайн-видео
}
}async avPlayerDataSrcDemo
// Создать объект экземпляра avPlayer
let avPlayer: media.AVPlayer = await media.createAVPlayer();
// Создайте функцию обратного вызова изменения конечного автомата
this.setAVPlayerCallback(avPlayer);
// Адрес источника воспроизведения в режиме воспроизведения dataSrc. Когда воспроизведение находится в режиме поиска, fileSize — это конкретный размер воспроизводимого файла, который будет присвоен ценой ниже.
let src: media.AVDataSrcDescriptor = {
  fileSize: -1,
  callback: (buf: ArrayBuffer, length: number, pos: number | undefined) => {
    let num = 0;
    if (buf == undefined || length == undefined || pos == undefined) {
      return -1;
    }
    num = fs.readSync(this.fd, buf, { offset: pos, length: length });
    if (num > 0 && (this.fileSize >= pos)) {
      return num;
    }
    return -1;
  }
}
let context = getContext(this) as common.UIAbilityContext;
// Получите адрес песочницы filesDir через UIAbilityContext, взяв в качестве примера модель Stage.
let pathDir = context.filesDir;
let path = pathDir + '/H264_AAC.mp4';
await fs.open(path).then((file: fs.File) => {
  this.fd = file.fd;
})
// Получить размер воспроизводимого файла
this.fileSize = fs.statSync(path).size;
src.fileSize = this.fileSize;
avPlayer.dataSrc = src;
}
}

3. Используйте интерфейс управления ресурсами, чтобы получить файлы мультимедийных ресурсов, упакованные в HAP, и воспроизвести их с помощью атрибута fdSrc.

Язык кода:ts
копировать
async avPlayerFdSrcDemo() {
  // Создать объект экземпляра avPlayer
  this.player = await media.createAVPlayer();
  // Создайте функцию обратного вызова изменения конечного автомата
  this.setAVPlayerCallback(this.player);
  // Получите адрес воспроизведения медиа-ресурса через интерфейс getRawFd члена resourcesManager UIAbilityContext.
  // Тип возвращаемого значения — {fd,offset,length}, fd — адрес fd пакета HAP, offset — смещение медиаресурса, а length — продолжительность воспроизведения.
  let context = getContext(this) as common.UIAbilityContext;
  let fileDescriptor = await context.resourceManager.getRawFd('1234.mp4');
  let avFileDescriptor: media.AVFileDescriptor =
    { fd: fileDescriptor.fd, offset: fileDescriptor.offset, length: fileDescriptor.length };
  // Назначение ценить fdSrc запускает отчет об инициализированном конечном автомате.
  this.player.fdSrc = avFileDescriptor;
}

4. Используйте файловую систему fs, чтобы открыть адрес песочницы, получить адрес медиафайла и воспроизвести его через атрибут URL.

Язык кода:ts
копировать
async avPlayerUrlDemo() {
  // Создать объект экземпляра avPlayer
  this.player = await media.createAVPlayer();
  this.setAVPlayerCallback(this.player);
  let fdPath = 'fd://';
  let context = getContext(this) as common.UIAbilityContext;
  // Получите адрес песочницы filesDir через UIAbilityContext, взяв в качестве примера модель Stage.
  let pathDir = context.filesDir;
  console.info(pathDir)
  let path = pathDir + '/1234.mp4';
  // Откройте соответствующий адрес файла ресурсов, чтобы получить fd, и назначьте цену URL-адресу, чтобы вызвать отчет об инициализированном конечном автомате.
  let file = await fs.open(path);
  fdPath = fdPath + '' + file.fd;
  this.player.url = fdPath;
}

2.3 Установите события прослушивания, необходимые для бизнеса

Поддерживаемые события прослушивания включают в себя:

тип события

иллюстрировать

stateChange

Необходимое событие для отслеживания изменения атрибута состояния игрока.

error

Необходимые события для отслеживания сообщений об ошибках игрока.

durationUpdate

Используется для индикаторов выполнения, отслеживания длины индикатора выполнения и продолжительности обновления ресурсов.

timeUpdate

Используется для индикаторов выполнения, отслеживает текущее положение индикатора выполнения и обновляет текущее время.

seekDone

Отвечайте на вызовы API и отслеживайте выполнение запросов Seek(). Если после использования функции поиска() для перехода к указанной позиции воспроизведения операция поиска будет успешной, об этом событии будет сообщено.

speedDone

Отвечайте на вызовы API и отслеживайте выполнение запросов setSpeed(). После использования setSpeed() для установки скорости воспроизведения, если операция setSpeed ​​прошла успешно, об этом событии будет сообщено.

volumeChange

Отвечайте на вызовы API и отслеживайте выполнение запросов setVolume(). После использования setVolume() для регулировки громкости воспроизведения, если операция setVolume прошла успешно, об этом событии будет сообщено.

bitrateDone

Отвечайте на вызовы API, используемые для потоков протокола HLS, и отслеживайте выполнение запросов setBitrate(). После использования setBitrate() для указания скорости передачи данных при воспроизведении, если операция setBitrate завершится успешно, об этом событии будет сообщено.

availableBitrates

Используется для потоков протокола HLS, дополнительные битрейты для мониторинга ресурсов HLS, используемые в setBitrate().

bufferingUpdate

Используется для сетевого воспроизведения, мониторинга информации буфера сетевого воспроизведения.

startRenderFrame

Используется для воспроизведения видео, отслеживая время рендеринга первого кадра воспроизведения видео. Когда AVPlayer впервые начинает вещание и переходит в состояние воспроизведения, об этом событии будет сообщено, когда на экране дисплея будет отображен первый кадр видео. Приложения обычно могут использовать это событие, чтобы сообщить и удалить видеообложку, чтобы обеспечить плавное соединение между обложкой и видеоэкраном.

videoSizeChange

Используется для воспроизведения видео, отслеживает информацию о ширине и высоте воспроизведения видео и может использоваться для настройки размера и пропорций окна.

audioInterrupt

Отслеживайте информацию о переключении фокуса звука и используйте ее с атрибутом audioInterruptMode. Если на текущем устройстве воспроизводится несколько мультимедиа, об этом событии будет сообщено при переключении аудиофокуса (то есть при воспроизведении других медиафайлов, таких как звонки и т. д.), и приложение сможет своевременно обработать его.

Язык кода:ts
копировать
avPlayer.on('speedDone', (number: Number) => this.speedDone(number));
 
avPlayer.on('seekDone', (number: Number) => this.seekDone(number));

2.4 Окно настроек

Тип XComponent установлен на SURFACE. Когда тип установлен на SURFACE, он может поддерживать событие Load. Функция события Load заключается в обратном вызове события при загрузке подключаемого модуля и установке ресурсов. играл в обратном вызове.

Язык кода:ts
копировать
build()
Column() {
  XComponent({
    id: 'AVPlayer',
    type: XComponentType.SURFACE,
    controller: this.xComponentController
  })
    .onLoad (()=> {
      this.surfaceID = this.xComponentController.getXComponentSurfaceId()
      this.xComponentContext = this.xComponentController.getXComponentContext() as Record<string, () => void>
    })

2.5 Регистрация функции обратного вызова avplayer

  • режим ожидания: состояние ожидания,AVPlayer только что был создан после createAVPlayer() и вызова метода reset().,Войдите в состояние ожидания. Создайте createAVPlayer() в первый раз.,Все свойства оценены по умолчанию. Вызов метода сброса(), атрибут URL или fdSrcilidataSrc и атрибут цикла будут сброшены.,Свойства, установленные другими пользователями, будут сохранены.
  • инициализировано: инициализация ресурса в режиме ожидания Настройки статуса urlили fdSrc, AVPlayer перейдет в инициализированное состояние. В это время можно настроить статические атрибуты, такие как окно и звук.
  • «Подготовлено»: состояние «Подготовлено». Когда метод «подготовить()» вызывается в инициализированном состоянии, AVPlayer перейдет в подготовленное состояние. В это время ресурсы механизма воспроизведения готовы.
  • воспроизведение: состояние воспроизведения. Вызовите метод play() в состоянии подготовки/приостановки/завершения, и AVPlayer перейдет в состояние воспроизведения.
  • пауза: состояние паузы, вызовите метод паузы в состоянии воспроизведения, AVPlayer перейдет в состояние паузы.
  • завершено: воспроизведение до конечного состояния. Когда медиа-ресурс воспроизводится до конца, если пользователь не настроил циклическое воспроизведение, AVPlayer перейдет в завершенное состояние.
  • остановлено: остановленное состояние,Вызовите метод stop() в состоянии подготовки/воспроизведения/приостановки/завершения.,AVPlayer перейдет в остановленное состояние,В это время механизм воспроизведения сохранит только атрибуты,Но это освободит ресурсы памяти,Вы можете вызвать методprepre(), чтобы подготовиться еще раз.,Вы также можете вызвать функцию сброса() для сброса.,Или вызовите Release(), чтобы полностью уничтожить его.
  • освобождено: уничтожить состояние, уничтожить механизм воспроизведения, связанный с текущим AVPlayer, и больше нельзя будет совершать переходы между состояниями. После вызова метода Release() он перейдет в освобожденное состояние и завершит процесс.
Язык кода:ts
копировать
private setAVPlayerCallback(avPlayer: media.AVPlayer) {
  if (this.player == null) {
    return;
  }
  // // Отвечайте на вызовы API и отслеживайте выполнение запросов Seek().
  avPlayer.on('speedDone', (number: Number) => this.speedDone(number));
  avPlayer.on('seekDone', (number: Number) => this.seekDone(number));
  // Функция обратного вызова изменения конечного автомата
  avPlayer.on('stateChange', async (state: string, reason: media.StateChangeReason) => {
    switch (state) {
      case 'idle': // После успешного вызова интерфейса сброса запускается отчет конечного автомата.
        console.info('AVPlayer state idle called.');
        break;
      case 'initialized': // avplayer Этот отчет о состоянии активируется после установки источника воспроизведения.
        console.info('AVPlayer state initialized called.');
        avPlayer.surfaceId = this.surfaceID; // Установите экран дисплея. Нет необходимости настраивать его, если воспроизводимый ресурс представляет собой чистый звук.
        avPlayer.prepare();
        break;
      case 'prepared': // Сообщите о конечном автомате после успешного завершения вызова подготовки.
        console.info('AVPlayer state prepared called.');
        avPlayer.play(); // Вызовите интерфейс воспроизведения, чтобы начать воспроизведение.
        break;
      case 'playing': // После успешного вызова игры конечный автомат срабатывает и сообщает
        console.info('AVPlayer state playing called.');
        break;
      case 'paused': // После успешного вызова паузы конечный автомат срабатывает и сообщает
        console.info('AVPlayer state paused called.');
        break;
      case 'completed': // После завершения воспроизведения конечный автомат срабатывает и сообщает
        console.info('AVPlayer state completed called.');
        avPlayer.stop(); //Вызываем интерфейс завершения воспроизведения
        break;
      case 'stopped': // После успешного вызова интерфейса остановки конечный автомат срабатывает и сообщает
        console.info('AVPlayer state stopped called.');
        avPlayer.release();
        break;
      case 'released':
        console.info('AVPlayer state released called.');
        break;
      default:
        console.info('AVPlayer state unknown called.');
        break;
    }
  })
}

2.6 Управление воспроизведением

1. Пауза и воспроизведение

Язык кода:ts
копировать
Button('start')
  .onClick(() => {
    this.avPlayerDataSrcNOSeekDemo()
  })
  .margin({right:12})
  .margin({top:5})
  .width(150)

Button('paused')
  .onClick(() => {
    this.player?.pause();
  })
  .margin({right:12})
  .margin({top:5})
  .width(150)
 
Button('player')
  .onClick(() => {
    this.player?.play();
  })
  .margin({right:12})
  .margin({top:5})
  .width(150)

2. Перестаньте играть и уничтожьте

Язык кода:ts
копировать
Button('stop')
  .onClick(() => {
    this.player?.stop();
  })
  .margin({right:12})

3. Сброс переключения видео

Язык кода:ts
копировать
Button('stop')
  .onClick(() => {
    this.player?.stop();
  })
  .margin({right:12})

4. Здесь установлена ​​двойная скорость для воспроизведения на двойной скорости, можно добиться, установив перечисление PlaybackSpeed. Здесь установлена ​​настройка SPEED_FORWARD_2_00_X, двойная скорость.

Язык кода:ts
копировать
Button('speed')
  .onClick(() => {
    this.player?.setSpeed(media.PlaybackSpeed.SPEED_FORWARD_2_00_X);
  })
  .margin({right:12})

5. Поиск перехода переходит к указанной позиции воспроизведения. Его можно вызвать только в состоянии подготовки/воспроизведения/приостановки/завершения. Единица измерения времени перехода – мс. Режим перехода контролируется установкой значения перечисления.

имя

ценить

иллюстрировать

SEEK_NEXT_SYNC

0

Указывает переход к следующему ключевому кадру в указанный момент времени.,Рекомендуется использовать это перечисление ценить при быстрой перемотке вперед.

SEEK_PREV_SYNC

1

Указывает переход к предыдущему ключевому кадру в указанный момент времени.,Рекомендуется использовать это перечисление при быстрой перемотке вперед.

SEEK_CLOSEST

2

Представляет переход к ближайшему кадру к указанному моменту времени.,Рекомендуется использовать это перечисление ценить при точном поиске.

напиши в конце

Если вы считаете, что этот контент вам очень полезен, я хотел бы предложить вам оказать мне три небольшие услуги:

  • Лайки, репосты и ваши «лайки и комментарии» — движущая сила моего творчества;
  • сосредоточиться на Редактор,В то же время вы можете рассчитывать на последующие статьи🚀,Делитесь оригинальными знаниями время от времени;
  • Если вы хотите получить более полные знания о последних знаниях Хунмэна, вы можете следить за станцией B: Ma Niu Classroom Hongmeng Development;
boy illustration
Учебное пособие по Jetpack Compose для начинающих, базовые элементы управления и макет
boy illustration
Код js веб-страницы, фон частицы, код спецэффектов
boy illustration
【новый! Суперподробное】Полное руководство по свойствам компонентов Figma.
boy illustration
🎉Обязательно к прочтению новичкам: полное руководство по написанию мини-программ WeChat с использованием программного обеспечения Cursor.
boy illustration
[Забавный проект Docker] VoceChat — еще одно приложение для мгновенного чата (IM)! Может быть встроен в любую веб-страницу!
boy illustration
Как реализовать переход по странице в HTML (html переходит на указанную страницу)
boy illustration
Как решить проблему зависания и низкой скорости при установке зависимостей с помощью npm. Существуют ли доступные источники npm, которые могут решить эту проблему?
boy illustration
Серия From Zero to Fun: Uni-App WeChat Payment Practice WeChat авторизует вход в систему и украшает страницу заказа, создает интерфейс заказа и инициирует запрос заказа
boy illustration
Серия uni-app: uni.navigateЧтобы передать скачок значения
boy illustration
Апплет WeChat настраивает верхнюю панель навигации и адаптируется к различным моделям.
boy illustration
JS-время конвертации
boy illustration
Обеспечьте бесперебойную работу ChromeDriver 125: советы по решению проблемы chromedriver.exe не найдены
boy illustration
Поле комментария, щелчок мышью, специальные эффекты, js-код
boy illustration
Объект массива перемещения объекта JS
boy illustration
Как открыть разрешение на позиционирование апплета WeChat_Как использовать WeChat для определения местонахождения друзей
boy illustration
Я даю вам два набора из 18 простых в использовании фонов холста Power BI, так что вам больше не придется возиться с цветами!
boy illustration
Получить текущее время в js_Как динамически отображать дату и время в js
boy illustration
Вам необходимо изучить сочетания клавиш vsCode для форматирования и организации кода, чтобы вам больше не приходилось настраивать формат вручную.
boy illustration
У ChatGPT большое обновление. Всего за 45 минут пресс-конференция показывает, что OpenAI сделал еще один шаг вперед.
boy illustration
Copilot облачной разработки — упрощение разработки
boy illustration
Микросборка xChatGPT с низким кодом, создание апплета чат-бота с искусственным интеллектом за пять шагов
boy illustration
CUDA Out of Memory: идеальное решение проблемы нехватки памяти CUDA
boy illustration
Анализ кластеризации отдельных ячеек, который должен освоить каждый&MarkerгенетическийВизуализация
boy illustration
vLLM: мощный инструмент для ускорения вывода ИИ
boy illustration
CodeGeeX: мощный инструмент генерации кода искусственного интеллекта, который можно использовать бесплатно в дополнение к второму пилоту.
boy illustration
Машинное обучение Реальный бой LightGBM + настройка параметров случайного поиска: точность 96,67%
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция без кодирования и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
LM Studio для создания локальных больших моделей
boy illustration
Как определить количество слоев и нейронов скрытых слоев нейронной сети?
boy illustration
[Отслеживание целей] Подробное объяснение ByteTrack и детали кода