Как использовать медиаплеер в FireMonkey, чтобы отображаться на форме, а не внешне? - PullRequest
0 голосов
/ 02 июля 2019

Я написал проект в качестве примера: http://docwiki.embarcadero.com/RADStudio/Rio/en/Building_a_Basic_Media_Player и запустить для Windows, но когда я воспроизводю видео, это отображается в окне за пределами формы, которая содержит mediaplayercontrol и медиаплеер. Пример для Delphi Rio, но у меня Delphi Tokyo 10.2.3, хотя я не думаю, что это проблема. Есть ли способ обойти это? Не говорите мне, что они должны обновить Rad Studio, это слишком дорого:

enter image description here

Код формы:

object Form2: TForm2
 Left = 0
 Top = 0
 Caption = 'Form2'
 ClientHeight = 480
 ClientWidth = 757
 FormFactor.Width = 320
 FormFactor.Height = 480
 FormFactor.Devices = [Desktop]
 OnDestroy = FormDestroy
 DesignerMasterStyle = 0
 object MainLayout: TLayout
   Align = Left
   Size.Width = 457.000000000000000000
   Size.Height = 480.000000000000000000
   Size.PlatformDefault = False
   TabOrder = 0
   object ControlPlayLayout: TLayout
     Align = Bottom
     Position.Y = 392.000000000000000000
     Size.Width = 457.000000000000000000
     Size.Height = 88.000000000000000000
     Size.PlatformDefault = False
     TabOrder = 0
     object prev: TButton
       Position.X = 16.000000000000000000
       Position.Y = 16.000000000000000000
       Size.Width = 41.000000000000000000
       Size.Height = 22.000000000000000000
       Size.PlatformDefault = False
       TabOrder = 0
       Text = 'Prev'
       OnClick = prevClick
     end
     object play: TButton
       Position.X = 56.000000000000000000
       Position.Y = 16.000000000000000000
       Size.Width = 41.000000000000000000
       Size.Height = 22.000000000000000000
       Size.PlatformDefault = False
       TabOrder = 1
       Text = 'Play'
       OnClick = playClick
     end
     object pause: TButton
       Position.X = 96.000000000000000000
       Position.Y = 16.000000000000000000
       Size.Width = 33.000000000000000000
       Size.Height = 22.000000000000000000
       Size.PlatformDefault = False
       TabOrder = 2
       Text = 'Pause'
       OnClick = pauseClick
     end
     object stop: TButton
       Action = MediaPlayerStop1
       Enabled = True
       ImageIndex = -1
       Position.X = 128.000000000000000000
       Position.Y = 16.000000000000000000
       Size.Width = 41.000000000000000000
       Size.Height = 22.000000000000000000
       Size.PlatformDefault = False
       TabOrder = 3
     end
     object next: TButton
       Position.X = 168.000000000000000000
       Position.Y = 16.000000000000000000
       Size.Width = 49.000000000000000000
       Size.Height = 22.000000000000000000
       Size.PlatformDefault = False
       TabOrder = 4
       Text = 'Next'
       OnClick = nextClick
     end
     object PositionTrackBar: TTrackBar
       Action = MediaPlayerCurrentTime1
       Align = Top
       CanParentFocus = True
       Enabled = True
       Orientation = Horizontal
       Size.Width = 457.000000000000000000
       Size.Height = 19.000000000000000000
       Size.PlatformDefault = False
       TabOrder = 5
     end
     object VolumeTrackBar: TTrackBar
       Action = MediaPlayerVolume1
       CanParentFocus = True
       Enabled = True
       Orientation = Horizontal
       Position.X = 232.000000000000000000
       Position.Y = 15.000000000000000000
       TabOrder = 6
     end
     object ShuffleCheckBox: TCheckBox
       Position.X = 320.000000000000000000
       Position.Y = 16.000000000000000000
       TabOrder = 7
       Text = 'ShuffleCheckBox'
       OnChange = ShuffleCheckBoxChange
     end
   end
   object TextLayout: TLayout
     Align = Top
     Size.Width = 457.000000000000000000
     Size.Height = 50.000000000000000000
     Size.PlatformDefault = False
     TabOrder = 1
     object NameLabel: TLabel
       Text = 'NameLabel'
       TabOrder = 3
     end
     object DurationLabel: TLabel
       Position.Y = 24.000000000000000000
       Text = 'DurationLabel'
       TabOrder = 4
     end
   end
   object MediaPlayerControl1: TMediaPlayerControl
     Size.Width = 457.000000000000000000
     Size.Height = 342.000000000000000000
     Size.PlatformDefault = False
     Align = Client
   end
 end
 object PlayListLayout: TLayout
   Align = Client
   Size.Width = 300.000000000000000000
   Size.Height = 480.000000000000000000
   Size.PlatformDefault = False
   TabOrder = 5
   object ControlPlayListLayout: TLayout
     Align = Bottom
     Position.Y = 416.000000000000000000
     Size.Width = 300.000000000000000000
     Size.Height = 64.000000000000000000
     Size.PlatformDefault = False
     TabOrder = 0
     object AddFiles: TButton
       Position.X = 16.000000000000000000
       Position.Y = 24.000000000000000000
       TabOrder = 0
       Text = 'AddFiles'
       OnClick = AddFilesClick
     end
     object ClearAll: TButton
       Position.X = 104.000000000000000000
       Position.Y = 24.000000000000000000
       TabOrder = 1
       Text = 'ClearAll'
       OnClick = ClearAllClick
     end
     object Clear: TButton
       Position.X = 192.000000000000000000
       Position.Y = 24.000000000000000000
       TabOrder = 2
       Text = 'Clear'
       OnClick = ClearClick
     end
   end
   object PlayListBox: TListBox
     Align = Client
     Size.Width = 300.000000000000000000
     Size.Height = 416.000000000000000000
     Size.PlatformDefault = False
     TabOrder = 1
     OnDblClick = PlayListBoxDblClick
     DisableFocusEffect = True
     DefaultItemStyles.ItemStyle = ''
     DefaultItemStyles.GroupHeaderStyle = ''
     DefaultItemStyles.GroupFooterStyle = ''
     Viewport.Width = 296.000000000000000000
     Viewport.Height = 412.000000000000000000
   end
 end
 object MediaPlayer1: TMediaPlayer
   Left = 24
   Top = 232
 end
 object OpenDialog1: TOpenDialog
   Left = 24
   Top = 176
 end
 object Timer1: TTimer
   OnTimer = Timer1Timer
   Left = 24
   Top = 120
 end
 object ActionList1: TActionList
   Left = 24
   Top = 64
   object MediaPlayerStop1: TMediaPlayerStop
     Category = 'Media Library'
     MediaPlayer = MediaPlayer1
   end
   object MediaPlayerCurrentTime1: TMediaPlayerCurrentTime
     Category = 'Media Library'
     MediaPlayer = MediaPlayer1
   end
   object MediaPlayerVolume1: TMediaPlayerVolume
     Category = 'Media Library'
     MediaPlayer = MediaPlayer1
   end
 end
end

Код органов управления:


    unit Unit2;

    interface

    uses
      System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
      FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Layouts,
      FMX.Media, FMX.Controls.Presentation, FMX.StdCtrls, System.Actions,
      FMX.ActnList, FMX.ListBox, FMX.StdActns;

    type
      TForm2 = class(TForm)
        MainLayout: TLayout;
        ControlPlayLayout: TLayout;
        TextLayout: TLayout;
        MediaPlayerControl1: TMediaPlayerControl;
        prev: TButton;
        play: TButton;
        pause: TButton;
        stop: TButton;
        next: TButton;
        MediaPlayer1: TMediaPlayer;
        OpenDialog1: TOpenDialog;
        Timer1: TTimer;
        ActionList1: TActionList;
        PositionTrackBar: TTrackBar;
        VolumeTrackBar: TTrackBar;
        ShuffleCheckBox: TCheckBox;
        PlayListLayout: TLayout;
        ControlPlayListLayout: TLayout;
        PlayListBox: TListBox;
        AddFiles: TButton;
        ClearAll: TButton;
        Clear: TButton;
        MediaPlayerStop1: TMediaPlayerStop;
        MediaPlayerCurrentTime1: TMediaPlayerCurrentTime;
        MediaPlayerVolume1: TMediaPlayerVolume;
        NameLabel: TLabel;
        DurationLabel: TLabel;
        procedure AddFilesClick(Sender: TObject);
        procedure ClearAllClick(Sender: TObject);
        procedure ClearClick(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure playClick(Sender: TObject);
        procedure PlayListBoxDblClick(Sender: TObject);
        procedure pauseClick(Sender: TObject);
        procedure nextClick(Sender: TObject);
        procedure prevClick(Sender: TObject);
        procedure Timer1Timer(Sender: TObject);
        procedure ShuffleCheckBoxChange(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
        Played: array of integer;
        CurrentPlayedIndex: integer;
        procedure AddToPlayedList(Index: integer);
        procedure DisplayText(str: string);
        procedure PlayNext();
        procedure FindAndPlay(Index: integer);
      end;

      TMediaEntry = class(TObject)
      public
        Path: String;
        constructor Create(FilePath: String);
      end;

    var
      Form2: TForm2;

    implementation

    {$R *.fmx}

    procedure TForm2.AddFilesClick(Sender: TObject);
    var
      Files: TStrings;
      I: integer;
      MediaEntry: TMediaEntry;
    begin
      // Sets the Filter so only the supported files to be displayed
      OpenDialog1.Filter := TMediaCodecManager.GetFilterString;
      if (OpenDialog1.Execute) then
      begin
        Files := OpenDialog1.Files;
        for I := 0 to Files.Count - 1 do
        begin
          MediaEntry := TMediaEntry.Create(Files[I]);
          PlayListBox.Items.AddObject(extractFileName(Files[I]), MediaEntry);
        end;
      end;

    end;

    procedure TForm2.AddToPlayedList(Index: integer);
    var
      Len: integer;
    begin
      Len := Length(Played);
      SetLength(Played, Len + 1);
      Played[Len] := Index;
      CurrentPlayedIndex := Len;
      PlayListBox.ItemIndex := index;
    end;

    procedure TForm2.ClearAllClick(Sender: TObject);
    var
      I: integer;
    begin
      if (PlayListBox.Count > 0) then
      begin
        for I := 0 to PlayListBox.Count - 1 do
          PlayListBox.Items.Objects[I].Free;
        PlayListBox.Clear;
        PlayListBox.ItemIndex := -1;
        SetLength(Played, 0);
        CurrentPlayedIndex := -1;
        MediaPlayer1.Clear;
        NameLabel.Text := '';
        DurationLabel.Text := '';
      end;

    end;

    procedure TForm2.ClearClick(Sender: TObject);
    var
      I, J: integer;
    begin
      if PlayListBox.Count < 0 then
        Exit;
      PlayListBox.Items.Objects[PlayListBox.ItemIndex].Free;
      PlayListBox.Items.Delete(PlayListBox.ItemIndex);
      J := 0;
      // Makes sure that the deleted media is not on the Playlist
      while J < Length(Played) - 1 do
      begin
        if (Played[J] = PlayListBox.ItemIndex) then
        begin
          for I := J to Length(Played) - 1 do
            Played[I] := Played[I + 1];
          SetLength(Played, Length(Played) - 1);
        end;
        J := J + 1;
      end;

    end;

    procedure TForm2.DisplayText(str: string);

    var
      DurationMin, DurationSec: integer;
    begin
      NameLabel.Text := str;
      DurationMin := MediaPlayer1.Duration div 10000 div 60000;
      DurationSec := MediaPlayer1.Duration div 10000 mod 60000 div 1000;
      DurationLabel.Text := IntToStr(DurationMin) + ':' + IntToStr(DurationSec);
    end;

    procedure TForm2.FindAndPlay(Index: integer);
    begin
      MediaPlayer1.Clear;
      PositionTrackBar.Value := PositionTrackBar.Min;
      if Index >= PlayListBox.Items.Count then
        Index := 0;
      MediaPlayer1.FileName := TMediaEntry(PlayListBox.Items.Objects[Index]).Path;
      if MediaPlayer1.Media <> nil then
      begin
        MediaPlayer1.Play;
        DisplayText(extractFileName(MediaPlayer1.FileName));
      end;
    end;

    procedure TForm2.FormDestroy(Sender: TObject);
    var
      I: integer;
    begin
      if (PlayListBox.Count > 0) then
        for I := 0 to PlayListBox.Count - 1 do
          PlayListBox.Items.Objects[I].Free;

    end;

    procedure TForm2.nextClick(Sender: TObject);
    begin
      if (PlayListBox.Count > 0) then
      begin
        PlayNext;
      end;
    end;

    procedure TForm2.pauseClick(Sender: TObject);
    begin
      if MediaPlayer1.Media <> nil then
        MediaPlayer1.Stop;
    end;

    procedure TForm2.playClick(Sender: TObject);
    begin
      if MediaPlayer1.Media <> nil then
      begin
        if (MediaPlayer1.State = TMediaState.Stopped) and
          (MediaPlayer1.CurrentTime < MediaPlayer1.Duration) then
        begin
          MediaPlayer1.Play;
          DisplayText(extractFileName(MediaPlayer1.FileName));
        end
        else
        begin
          MediaPlayer1.CurrentTime := 0;
        end;
      end
      else
      begin
        if (PlayListBox.Count = 0) then
          Exit;
        if (PlayListBox.ItemIndex = -1) then
          PlayListBox.ItemIndex := 0;
        FindAndPlay(PlayListBox.ItemIndex);
        if (ShuffleCheckBox.IsChecked) then
          AddToPlayedList(PlayListBox.ItemIndex);
      end;
    end;

    procedure TForm2.PlayListBoxDblClick(Sender: TObject);
    begin
      if (PlayListBox.Count < 0) then
        Exit;
      MediaPlayer1.Clear;
      MediaPlayer1.FileName:= TMediaEntry(
        PlayListBox.Items.Objects[PlayListBox.ItemIndex]).Path;
      if MediaPlayer1.Media <> nil then
      begin
        MediaPlayer1.Play;
        DisplayText(extractFileName(MediaPlayer1.FileName));
        AddToPlayedList(PlayListBox.Items.IndexOf
          (extractFileName(MediaPlayer1.FileName)));
      end;
    end;

    procedure TForm2.PlayNext;

     var
      Index: integer;
    begin
      if (ShuffleCheckBox.IsChecked) then
      begin
        if (CurrentPlayedIndex < Length(Played) - 1) then
        begin
          CurrentPlayedIndex := CurrentPlayedIndex + 1;
          FindAndPlay(Played[CurrentPlayedIndex]);
        end
        else
        begin
          Index := Random(PlayListBox.Count - 1);
          FindAndPlay(Index);
          AddToPlayedList(Index);
        end;
        PlayListBox.ItemIndex := Played[CurrentPlayedIndex];
      end
      else
      begin
        FindAndPlay(PlayListBox.ItemIndex + 1);
        PlayListBox.ItemIndex := PlayListBox.ItemIndex + 1;
      end;
    end;

    procedure TForm2.prevClick(Sender: TObject);
    begin
      if ShuffleCheckBox.IsChecked then
      begin
        if (Length(Played) > 0) and (CurrentPlayedIndex > 0) then
        begin
          CurrentPlayedIndex := CurrentPlayedIndex - 1;
          FindAndPlay(Played[CurrentPlayedIndex]);
          PlayListBox.ItemIndex := Played[CurrentPlayedIndex];
        end;
      end
      else if (PlayListBox.ItemIndex > 0) then
      begin
        FindAndPlay(PlayListBox.ItemIndex - 1);
        PlayListBox.ItemIndex := PlayListBox.ItemIndex - 1;
      end;
    end;

    procedure TForm2.ShuffleCheckBoxChange(Sender: TObject);
    begin
        If (not ShuffleCheckBox.IsChecked) then
      begin
        SetLength(Played, 0);
        CurrentPlayedIndex := -1;
      end;
    end;

    procedure TForm2.Timer1Timer(Sender: TObject);
    begin
         if (MediaPlayer1.State = TMediaState.Playing) and
        (MediaPlayer1.CurrentTime = MediaPlayer1.Duration) then
        PlayNext;
    end;

    { TMediaEntry }

    constructor TMediaEntry.Create(FilePath: String);
    begin
        Path := FilePath;
    end;

    end.

...