HarmonyOS avplayer组件播放视频的时候,横屏,然后再浮窗,浮窗必定播放失败

HarmonyOS
2024-12-23 16:42:06
浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
shlp

xc+avplayer无缝切换的示例可以参考下:

EntryAbility页面:

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { AVPlayerDemo } from '../pages/AVPlayerDemo';
export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  }
  onDestroy(): void {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
  }
  onWindowStageCreate(windowStage: window.WindowStage): void {
    // Main window is created, set main page for this ability
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
    windowStage.loadContent('pages/XCAvplayer', (err) => {
      if (err.code) {
        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
        return;
      }
      AppStorage.setOrCreate('player', new AVPlayerDemo());
      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');
    });
  }
  onWindowStageDestroy(): void {
    // Main window is destroyed, release UI related resources
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  }
  onForeground(): void {
    // Ability has brought to foreground
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
  }
  onBackground(): void {
    // Ability has back to background
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.

XCAvplayer页面:

import { myVideoSourceDate, VideoSource } from './myVideoSourceDate';
import { VideoComponent } from './VideoComponent';

@Entry
@Component
struct XCAvplayer {
  private data: myVideoSourceDate = new myVideoSourceDate([]);
  @State isLayoutFullScreen : boolean = false;
  @State fangDaIndex : number = -1;

  aboutToAppear(): void {
    let list: VideoSource[] = [
      new VideoSource('文案0', 'https://xxx.mp4')
    ];
    console.log('myAppliction is Appear')
    this.data = new myVideoSourceDate(list);
  }

  build() {
    Scroll() {
      Column() {
        List() {
          LazyForEach(this.data, (item: VideoSource,index : number) => {
            ListItem() {
              VideoComponent({item : item, isLayoutFullScreen : this.isLayoutFullScreen, index : index , fangDaIndex : this.fangDaIndex})
                .visibility(this.isLayoutFullScreen && this.fangDaIndex !== index ? Visibility.None : Visibility.Visible)
            }
          }, (item: string) => item)
        }.cachedCount(5).scrollBar(BarState.Off).edgeEffect(this.isLayoutFullScreen ? EdgeEffect.None : EdgeEffect.Spring)
      }
    }
    .edgeEffect(this.isLayoutFullScreen ? EdgeEffect.None : EdgeEffect.Spring)
    .width('100%')
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.

VideoComponent页面:

import { AVPlayerDemo } from './AVPlayerDemo';
import { VideoSource } from './myVideoSourceDate';
import window from '@ohos.window';
import { BusinessError } from '@ohos.base';
import { router } from '@kit.ArkUI';

@Component
export struct VideoComponent {
  @ObjectLink item: VideoSource;
  index: number = -1;
  @Link isLayoutFullScreen: boolean;
  @Link fangDaIndex: number;
  @State bkColor: Color = Color.Red
  mXComponentController: XComponentController = new XComponentController();
  @State player_changed: boolean = false;
  // player: AVPlayerDemo = new AVPlayerDemo();
  player: AVPlayerDemo = AppStorage.get('player') as AVPlayerDemo
  // 设置窗口方向
  setR(orientation: number) {
    window.getLastWindow(getContext(this)).then((win) => {
      win.setPreferredOrientation(orientation).then((data) => {
        console.log('setWindowOrientation: ' + orientation + ' Succeeded. Data: ' + JSON.stringify(data));
      }).catch((err: string) => {
        console.log('setWindowOrientation: Failed. Cause: ' + JSON.stringify(err));
      });
    }).catch((err: string) => {
      console.log('setWindowOrientation: Failed to obtain the top window. Cause: ' + JSON.stringify(err));
    });
  }

  // 设置沉浸式窗口
  setFullScreen(isLayoutFullScreen: boolean) {
    window.getLastWindow(getContext(this)).then((win) => {
      win.setWindowLayoutFullScreen(isLayoutFullScreen, (err: BusinessError) => {
        const errCode: number = err.code;
        if (errCode) {
          console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(err));
          return;
        }
        console.info('Succeeded in setting the window layout to full-screen mode.');
      });
    }).catch((err: string) => {
      console.log('setWindowOrientation: Failed to obtain the top window. Cause: ' + JSON.stringify(err));
    });
  }

  build() {
    // 通过显隐控制控制其他listItrem是否展示
    Column() {
      Text(this.item.text)
        .visibility(this.isLayoutFullScreen === false ? Visibility.Visible : Visibility.None)
      Stack() {
        XComponent({ id: 'video_player_id', type: XComponentType.SURFACE, controller: this.mXComponentController })
          .onLoad(() => {
            this.player.setSurfaceID(this.mXComponentController.getXComponentSurfaceId());
            this.player_changed = !this.player_changed;
            this.player.avPlayerLiveDemo(0, this.item.url);
          })
        Row() {
          Button(this.isLayoutFullScreen ? '退出全屏' : '点击全屏')
            .onClick(() => {
              this.fangDaIndex = this.index
              this.isLayoutFullScreen = !this.isLayoutFullScreen;
              this.setR(this.isLayoutFullScreen ? 4 : 1)
              this.setFullScreen(this.isLayoutFullScreen)
            })
            .backgroundColor(this.bkColor)
          Button('跳转页面')
            .onClick(() => {
              this.player.pause();
              router.pushUrl({
                url: 'pages/PageSec'
              })
            })
            .backgroundColor(this.bkColor)
        }
      }
      .height(this.isLayoutFullScreen ? '100%' : 200)
    }
    .width('100%')
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.

PageSec页面:

import { AVPlayerDemo } from './AVPlayerDemo'

@Entry
@Component
struct PageSec {
  private surfaceId: string = '';
  xComponentController: XComponentController = new XComponentController();
  @State rect: SurfaceRect | null = null;
  player: AVPlayerDemo = AppStorage.get('player') as AVPlayerDemo;

  build() {
    Column() {
      XComponent({
        id: 'xcomponent',
        type: XComponentType.SURFACE,
        controller: this.xComponentController
      })
        .onLoad(() => {
          let surfaceRect: SurfaceRect = {
            offsetX: 0,
            offsetY: 0,
            surfaceWidth: 1200,
            surfaceHeight: 500
          };
          this.xComponentController.setXComponentSurfaceRect(surfaceRect);
          this.surfaceId = this.xComponentController.getXComponentSurfaceId()
          this.player.setSurfaceID(this.surfaceId);
          this.player.start();
        })
    }
    .width('100%')
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.

myVideoSourceDate页面:

export class myVideoSourceDate implements IDataSource {
  videoList: VideoSource[] = [];

  constructor(videoList: VideoSource[]) {
    this.videoList = videoList;
  }

  totalCount(): number {
    return this.videoList.length;
  }

  getData(index: number): VideoSource {
    return this.videoList[index];
  }

  registerDataChangeListener(listener: DataChangeListener): void {
  }

  unregisterDataChangeListener(listener: DataChangeListener): void {
  }
}

@Observed
export class VideoSource {
  text ?: string;
  url ?: string;

  constructor(text ?: string,url?: string) {
    this.text = text;
    this.url = url;
  }
}

import media from '@ohos.multimedia.media';
import { BusinessError } from '@ohos.base';

export class AVPlayerDemo {
  private count: number = 0;
  private surfaceID: string = '';
  private url: string = '';
  private avPlayer: media.AVPlayer | undefined;

  // 注册avplayer回调函数。
  setAVPlayerCallback() {
    // seek操作结果回调函数。
    this.avPlayer?.on('seekDone', (seekDoneTime: number) => {
      console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
    })
    // error回调监听函数,当avplayer在操作过程中出现错误时,调用reset接口触发重置流程。
    this.avPlayer?.on('error', (err: BusinessError) => {
      console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
      this.avPlayer?.reset();
    })
    // 状态机变化回调函数。
    this.avPlayer?.on('stateChange', async (state: string, reason: media.StateChangeReason) => {
      switch (state) {
        case 'idle':
          console.info('AVPlayer state idle called.');
          this.avPlayer?.release();
          break;
        case 'initialized':
          console.info('AVPlayer state initialized called.');
          if (this.avPlayer != null && this.avPlayer != undefined) {
            this.avPlayer.surfaceId = this.surfaceID;
          }
          this.avPlayer?.prepare();
          break;
        case 'prepared':
          console.info('AVPlayer state prepared called.');
          if (this.count === 0 || this.count === 1) {
            console.info('AVPlayer start to play.');
            if (this.avPlayer != null && this.avPlayer != undefined) {
              this.avPlayer.surfaceId = this.surfaceID;
            }
            this.avPlayer?.play();
          }
          break;
        case 'playing':
          console.info('AVPlayer state playing called.');
          if (this.avPlayer != null && this.avPlayer != undefined) {
            this.avPlayer.surfaceId = this.surfaceID
          }
          this.avPlayer?.play();
          break;
        case 'paused':
          console.info('AVPlayer state paused called.');
          this.avPlayer?.pause();
          break;
        case 'completed':
          console.info('AVPlayer state paused called.');
          this.avPlayer?.stop();
          break;
        case 'stopped':
          console.info('AVPlayer state stopped called.');
          this.avPlayer?.reset();
          break;
        case 'released':
          console.info('AVPlayer state released called.' + this.surfaceID);
          break;
        default:
          break;
      }
    })
  }

  async avPlayerLiveDemo(count: number, url ?: string, avplayer ?: media.AVPlayer) {
    this.count = count;
    if (url != undefined) {
      this.url = url;
    }
    this.avPlayer = await media.createAVPlayer();
    this.setAVPlayerCallback();
    this.avPlayer.url = url;
  }

  destroy() {
    this.avPlayer?.stop()
    this.avPlayer?.release()
    this.avPlayer = undefined
  }

  setSurfaceID(surface_id: string) {
    console.log('setSurfaceID : ' + surface_id);
    this.surfaceID = surface_id;
  }

  getAvPlayer(): media.AVPlayer | undefined {
    return this.avPlayer;
  }

  getSurfaceID(): string {
    return this.surfaceID;
  }

  setUrl(url: string) {
    this.url = url;
  }

  getUrl(): string {
    return this.url
  }

  start() {
    this.avPlayer?.play()
  }

  pause() {
    this.avPlayer?.pause();
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
分享
微博
QQ
微信
回复
2024-12-23 20:17:40
相关问题
如何实现全局效果
2234浏览 • 1回复 待解决
HarmonyOS 应用内点击事件相关
631浏览 • 1回复 待解决
HarmonyOS 播放视频时候禁止息
881浏览 • 1回复 待解决
AVPlayer实现视频播放
1984浏览 • 1回复 待解决
avplayer播放视频demo
3005浏览 • 1回复 待解决
应用如何适配华为悬浮?
3498浏览 • 1回复 待解决
HarmonyOS 播放问题
1438浏览 • 1回复 待解决
HarmonyOS AvPlayer视频播放速度问题
1375浏览 • 1回复 待解决
HarmonyOS video如何播放
1083浏览 • 1回复 待解决
HarmonyOS 视频播放AVPlayer解码异常
893浏览 • 1回复 待解决