• ChinaCock10.3.3激情版3的TCCSuperPlayerView,让app视频播放更完美


    在以前的文章中,有写过如何使用TCCSuperPlayerView实现app的视频播放功能,随着ChinaCock10.3.3激情版3的发布,使得视频播放更完美的与app集成。接下来,我们看看如何使用这个控件的新功能。

    在这个版本中,作者新增加一个事件OnBackPress,当用户按下视频播器上面的<返回时触发,其中参数APlayMode,指当前视频播放器的播放模式,AHandled:开发者来控制是否触发OnRequestPlayMode事件。为True时,不触发。下面是我的实现代码:

    procedure TPlayVideoForm.CCSuperPlayerView1BackPress(ASender: TObject; APlayMode: TCCSuperPlayerView_PLAYMODE;
      var AHandled: Boolean);
    begin
      // 将AHandled设置为True 控件则不会执行返回按钮的操作,就可以自己根据自己的业务情况编写点击返回按钮需要干的事情
      AHandled := false;
      case APlayMode of
        TCCSuperPlayerView_PLAYMODE.PLAYMODE_WINDOW:
          begin
            // showmessage('您在窗口模式下点击了返回!');
            self.CCSuperPlayerView1.OnPause;
            Close;
            AHandled := True;
          end;
        TCCSuperPlayerView_PLAYMODE.PLAYMODE_FULLSCREEN:
          begin
            if Application.FormFactor.Orientations = [TFormOrientation.Portrait] then
            begin
              self.CCSuperPlayerView1.OnPause;
              Close;
              AHandled := True;
            end;
    
            // showmessage('您在全屏模式下点击了返回!');
          end;
        TCCSuperPlayerView_PLAYMODE.PLAYMODE_FLOAT:
          begin
            // showmessage('您在浮窗模式下点击了返回!');
          end;
      end;
    end;

    当播放器处在PlayMode_Window,或者处在PlayMode_FullScreen并且是竖屏时,点返回,中止播放并返回到上一个界面。

    下面是处理的OnRequestPlayMode事件:

    procedure TPlayVideoForm.CCSuperPlayerView1RequestPlayMode(ASender: TObject; APlayMode: TCCSuperPlayerView_PLAYMODE);
    begin
    
      if APlayMode = TCCSuperPlayerView_PLAYMODE.PLAYMODE_FULLSCREEN then
      begin
        self.FullScreen := True;
        CCSuperPlayerView1.Parent := self;
        CCSuperPlayerView1.Align := TAlignLayout.Contents;
        Application.FormFactor.Orientations := [TFormOrientation.Landscape];
      end
      else if APlayMode = TCCSuperPlayerView_PLAYMODE.PLAYMODE_WINDOW then
      begin
        self.FullScreen := false;
        CCSuperPlayerView1.Parent := self.PlayerViewContainorLayout;
        CCSuperPlayerView1.Align := TAlignLayout.Contents;
        CC.Comm.App_BringToFront('com.kinglandsoft.zhlm');
        Application.FormFactor.Orientations := [TFormOrientation.Portrait];
      end
      else if APlayMode = TCCSuperPlayerView_PLAYMODE.PLAYMODE_FLOAT then
      begin
        CC.Comm.App_SendToBack;
      end;
    end;

    在这个事件中,处理视频播放器在不同模式下,app的适应情况。当进入FullScreen时,设置应用全屏并横置屏幕,达到和市面的app播放一样的效果。在Widows模式,对屏幕做竖向处理。

    最后,我们还要处理一下硬件返回,当用户按下这个返回键时,如果在全屏下,自动返回到竖屏,进入Window状态,再点返回,则返回到上一界面。不多说,直接看代码:

    procedure TPlayVideoForm.FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
    begin
      if (Key = vkHardwareBack) then
      begin
        case CCSuperPlayerView1.PlayMode of
          TCCSuperPlayerView_PLAYMODE.PLAYMODE_WINDOW:
            begin
              // showmessage('您在窗口模式下点击了返回!');
              self.CCSuperPlayerView1.OnPause;
              Close;
            end;
          TCCSuperPlayerView_PLAYMODE.PLAYMODE_FULLSCREEN:
            begin
              // RequestPlayMode方法会触发OnRequestPlayMode事件.
              CCSuperPlayerView1.RequestPlayMode(TCCSuperPlayerView_PLAYMODE.PLAYMODE_WINDOW);
              // showmessage('您在全屏模式下点击了返回!');
            end;
          TCCSuperPlayerView_PLAYMODE.PLAYMODE_FLOAT:
            begin
              CCSuperPlayerView1.RequestPlayMode(TCCSuperPlayerView_PLAYMODE.PLAYMODE_WINDOW);
              // showmessage('您在浮窗模式下点击了返回!');
            end;
        end;
        Key := 0;
      end;

    这里,用到了RequestPlayMode方法,这个方法会触发OnRequestPlayMode事件。这也是该版本实现的方法。

    上面,我们控制了播放窗口间以及播放窗口与app间的切换,合理的使用播放窗口上的“返回”以及硬键盘的返回键,接下来,我们还要考虑一种情况,就是app进入后台,比如手机来电的处理,要自动暂停播放,当用户重回app时自动播放。你总不能让用户在接电话时,还要听到播放器的声音。

    如何捕获到应用进入后台及返回呢?ChinaCock为我们提供了TCCFMXNativeActivityObserver,利用其提供的事件,可以方便的捕获到。如下图,进入后台,触发OnPause事件,返回时触发OnResume。

    有了对应的事件,代码就容易了,直接从ChinaCock的Demo中拿过来,注释都写好了。

    procedure TPlayVideoForm.CCFMXNativeActivityObserver1Pause(ASender: TObject);
    begin
      // 浮窗播放不暂停播放
      if CCSuperPlayerView1.PlayMode <> TCCSuperPlayerView_PLAYMODE.PLAYMODE_FLOAT
      then
      begin
        self.CCSuperPlayerView1.OnPause; // 这样app进入后台后就不会播放
      end;
    end;
    
    procedure TPlayVideoForm.CCFMXNativeActivityObserver1Resume(ASender: TObject);
    begin
      self.CCSuperPlayerView1.OnResume; // 这样app返回前台继续播放
    end;

    适应app与后台切换的自动暂停与播放,再往下来,就是窗口风格的设计了,做一个全黑的窗口是很有必要的。如下图,设置Fill.Color=Black,一个全黑的窗口就出来了。

    这就完事了,没有,一个完美的设计,还要适应屏上面的状态条及底部的虚拟导航条(俺用的华为手机),这时候,就需要ChinaCock的TCCSystemBar组件,具体用法很早之前也有写,在这里

    现在我们放置一个TCCSystemBar,然后在Form.OnCreate事件中设置状态条及导航条的高度:

    function TPlayVideoForm.GetNavigationBarHeight: Single;
    begin
      Result := 0;
      if self.CCSystemBar1.checkNavigationBarShow then
      begin
        Result := self.CCSystemBar1.getNavigationBarPointHeight;
      end
    end;
    
    procedure TPlayVideoForm.FormCreate(Sender: TObject);
    begin
      CCSystemBar1.TranslucentStatusBar; // 适应android 4.4.4
      StatusBar.Height := CCSystemBar1.getStatusBarPointHeight;
      NavigatorBar.Height := GetNavigationBarHeight;
    end;

    这时候,窗口的设计图如下:

    其中,StatusBar是一个置项的Layout,NavigatorBar是一个置底的Layout,分别用来占用状态条及导航条的位置。

    对于华为的虚拟导航条,用户还可以控制隐藏与显示,这怎么办呢?看似麻烦,处理起来简单,我们用一个Timer来控制,定时设置NavigatorBar的高度:

    procedure TPlayVideoForm.Timer1Timer(Sender: TObject);
    begin
       if Self.Visible then
          NavigatorBar.Height := GetNavigationBarHeight;//适应隐藏与显示虚拟导航条.
    end;

    间隔1秒触发一次就好了!

    再负点责任,让Timer该工作时工作,不该工作时休息,用Form.OnShow及OnHide事件处理:

    procedure TPlayVideoForm.FormHide(Sender: TObject);
    begin
      NavigatorBarTimer.Enabled:=False;
    end;
    
    procedure TPlayVideoForm.FormShow(Sender: TObject);
    begin
      NavigatorBarTimer.Enabled;//自动适应虚拟导航条的隐藏与显示
    
      if Screen.ActiveForm <> nil then
         Screen.ActiveForm.Focused := nil;
      CCSuperPlayerView1.ResetPlayer;
      CCSuperPlayerView1.Play('返回', url);
    
    end;

    再有一项设计需要实现,那就是自动记忆用户的播放进度,当用户重复播放同一视频时,能自动从上次的播放的位置开始。

    先取播放的位置,新版本TCCSuperPlayerView提供了一个事件OnPlayProgressEvent,其中,参数AProgress为进度,ADuration为视频的总时长,单位都是毫秒。接管这个事件,用变量FPosition1来保存播放进度,代码如下:

    procedure TPlayVideoForm.CCSuperPlayerView1PlayProgressEvent(ASender: TObject;
      AProgress, ADuration: Integer);
    begin
           FPosition1:=AProgress;
    end;

    有了播放进度,接下来是如何在播放时,自动跳转到这个位置呢?新版本TCCSuperPlayerView提供了一个事件OnPlayPrearedEvent,这个事件在调用Play方法后触发,实现一下这个事件的代码:

    procedure TPlayVideoForm.CCSuperPlayerView1PlayPreparedEvent(ASender: TObject);
    begin
      if FPosition>0 then
        CCSuperPlayerView1.SeekTo(Round(FPosition/1000));
    end;

    当播放进度大于0时,进行跳转,这里用到的SeekTo方法也是此版本实现的。需要注意,SeekTo的参数是秒。眼神好的朋友也许已经看到,这里我用的FPosition变量,而不是在OnPlayProgressEvent中捕获到进度的变量FPosition1,多了个1。为什么呢?因为当调用Play方法时,会在OnPlayPrearedEvent前触发PlayProgressEvent,造成这个FPosition1被改变,不再是上次保留的进度。

    现在再看一下播放视频的代码:

    procedure TPlayVideoForm.Start;
    begin
      if FOldURL = url then  //如果是上次播放视频,自动从上次播放位置开始
      begin
        FPosition:=FPosition1;//取上次播放进度并用FPosition来调用SeekTo方法
        CCSuperPlayerView1.Play('返回', url);
      end
      else
      begin
        FOldURL := url;
        FPosition:=0;//播放一个新视频时,进度清0,避免触发的PrepareEvent中从上次播放进度开始.
        CCSuperPlayerView1.Play('返回', url);
      end;
    end;

    代码我注释了,相信朋友你一看就明白。写到这里,如何自动记忆上次播放位置也算完成,但只是实现用户连续重复播放一个视频时有效,用户播放多个视频时,只能记忆最后一个视频的进度。如果自动记忆多个视频,需要保存每个视频的播放进度,我计划用本地表来保存,这里就不再写了。

    至此,一个高度与app集成,堪称完美的播放器功能就实现了!

    在实现的过程中,得到ChinaCock作者的大力支持,再此感谢作者的努力与付出!再次感谢!!另外,作者计划在下一版本中,更好的支持记忆进度并按照记忆的进度进行播放,期待了...

    如果你也想让自己的app具有如此完美的功能,记得进群223717588,但要知道,这是付费的控件。

  • 相关阅读:
    2015第二周日
    2015第二周六
    2015第二周五
    反思java web的发展
    servlet/filter/listener/interceptor区别与联系
    WSSecurity简述
    2015第2周一数据传输安全
    2015第一周日
    2015第1周六2015技术努力方向
    插入排序
  • 原文地址:https://www.cnblogs.com/kinglandsoft/p/12667279.html
Copyright © 2020-2023  润新知