Практика разработки 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
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
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