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