Recent

Author Topic: Lazarus Mediaplayer with SDL2 and FFMPEG  (Read 25401 times)

somby

  • New Member
  • *
  • Posts: 15
    • Sombys Softwareküche
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #15 on: April 23, 2018, 10:48:09 am »
Hi lazarus users,
I have found some small bugs yet. The latest version
is 006. You can found it at download:
https://c.1und1.de/@519844823566385489/Jae-lddLSjquAVnczAPqHg

have fun
your somby
Sombys Softwareküche
https://www.somby.de

metis

  • Sr. Member
  • ****
  • Posts: 300
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #16 on: April 27, 2018, 04:35:31 pm »
@somby

Forgot to tell You:
To see Stream-Starttimes and -Durations (and other StreamInfos), You may also implement
'av_dump_format()' in Your Code or use FFmpeg's 'ffprobe.exe':
https://www.ffmpeg.org/ffprobe.html

Quote
The biggest problem is to seek within a file.

That's, what I tried to tell You above ("it's getting even more complex, if You start Adding Features"):
Reading an AV-Stream is easy. Seeking synchronized(!) is a bit more complicated.
If You want to do all of this fast and accurate, it's even more complicated.
But it's getting really interesting, when You start Adding PlayerFeatures.

Quote
If I don't flush all buffers...If I flush all buffers after seeking
Here's another Dranger-like FFPlay-Code (not the newest one, but the BasicStructure is the same):
https://github.com/mpenkov/ffmpeg-tutorial or take the File in the Attachment 'ffmpeg-tutorial-master.zip'.

Quote
Ffplay has same problems, you can find it in documentation of ffplay...see "Seek with -ss pos".
This Part of the FFPlay-Documentation explains the Use of the ss-Commandline-Argument, that
sets an optional StartPosition. In this Context, the Doc mentions, that
"in most formats it is not possible to seek exactly" and that "ffplay will seek to the nearest seek point".
So far, so true, but:
1. In FFPlay, these Problems are solved by Code to keep the Tolerance as small as possible,
2. In FFPlay, the "Seek with -ss pos" is other than Seeking in the running Stream (see below).
3. The Seek itself has an Inaccuracy of only some MilliSeconds.
    (Suppose, max. the Half of the Pts-Diff between two Keyframes.)
4. The Precision of the Seek depends on Your Code:
Elder Versions of 'ffplay.c' and the current Version of 'FFPlay4Laz' use 'av_seek_frame()', that
"simply" seeks to the Keyframe at a Timestamp.
Newer Versions of 'ffplay.c' and You use 'avformat_seek_file()', that
seeks to a Timestamp(ts) within a given Range (...; min_ts, ts, max_ts: Int64; ...), whereat
the Seek-Mode and -Precision depend on that Range and some Flags.

ad SeekRange:
I don't think, that [-9223372036854775808..9223372036854775807] is a practical Choice.
'ffplay.c' uses that Range only to seek to a StartPosition; for the Range when Seeking in the Stream, see:
'ffplay.c' -> 'read_thread()' -> "int64_t seek_min" and "int64_t seek_max".
ad Flags:
You use 'AVSEEK_FLAG_ANY' (= "seek to any frame, even non key-frames"); 'ffplay.c' uses 'AVSEEK_FLAG_BYTE' to seek in Bytes.
-> If I got You right, You're currently Seeking to any FrameType within any Range.

In the Attachment some Pics to demonstrate the Precision, that I achieve with 'av_seek_frame()'
with several MRL-Formats, when 'Starting paused, at 10,000 Sec.' and 'Stepping paused +/- 3Sec., +/- 30Sec. +/- 3Min.':
'SeekAudio.7z' and 'SeekVideo.7z'

The shown Start- and EndTimes are the synchronized MRL-Positions before and after Seeking:
Seek-StartTime -> SeekStep -> Seek-EndTime -> Diff between Seek-EndTime and SeekTarget.
(The MRL-Position is, what the User would see as the "current PlayerPosition".)
Note:
With Videos, the Differences to the SeekTarget seem to be very big. This is due to the Code, that
stops the Seek in a paused MRL: It's stopped, when the corresponding VideoImage is displayed - this may last a bit.
(-> some better Code is projected.)
Of course, the Precision of the Seek in the Stream itself is much higher.


Quote
it is impossible to solute all the problems.
Which one ?

Quote
I think the player is working good anough...
I never doubted that. It's all a Question of what You want.
It's like the Difference between a Watch and a Chronometer, or between SDL-Audio and Portaudio+ASIO.

 :)
Life could be so easy, if there weren't those f*** Details.
My FFmpeg4Lazarus = FFPlay4Laz + FFGrab4Laz + FFInfo4Laz

ChristianH

  • New Member
  • *
  • Posts: 46
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #17 on: November 19, 2018, 09:54:42 am »
Hi,

this is my first post here and i'm sorry for digging this old topic out.
I played a bit with the Player and it is fairly reasonable written :) I just wondered why you focus the work on windows, because if you work under Windows it is most likely better to use Directshow instead. Anyhow i started porting your code to get it more platform independent. This means first to remove the Windows usage. CreateEvent is encapsulated into TEvent which works on all platforms. So i replaced your two Events. Same with your Threads.

The reason for writing is if i fix this, do you plan to add the changes into your code? And the other question is, i did not studied your explayer code (except those parts i mentioned above). Could you put the video rendering into a separated class? I don't want to use SDL for rendering, since i prefer OpenGL directly. Same with the audio part.

Christian

ChristianH

  • New Member
  • *
  • Posts: 46
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #18 on: November 20, 2018, 09:24:15 am »
Sorry for the monologue, but i managed to get the player running under Linux. There are only two issues. The first one is that i was unable to link the ffmpeg files which i created. Loading the binaries via get-apt worked, but i prefer to compile them by myself. Especially if you don't want to compile it with GPL decoders.

The second problem is caused by SDL2. This only works under Windows: FWindow := SDL_CreateWindowFrom(Pointer(Handle)); You need the Window handle, which does not work this way under linux. Does somebody have any idea how to get the handle?

https://ibb.co/hQ7vqL

Christian

Guva

  • Jr. Member
  • **
  • Posts: 82
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #19 on: November 20, 2018, 03:10:16 pm »
look towards the bare game. It uses sdl2 and runs fine on Linux. https://github.com/sysrpl/Bare.Game

ChristianH

  • New Member
  • *
  • Posts: 46
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #20 on: November 20, 2018, 07:18:08 pm »
Thanks for the response, i did not knew about this nice engine. Anyway it does not solve the problem, but

Code: Pascal  [Select][+][-]
  1. {$IFDEF MSWINDOWS}
  2.     FWindow := SDL_CreateWindowFrom(Pointer(Handle));
  3. {$ENDIF}
  4. {$IFDEF UNIX}
  5.     FWindow := SDL_CreateWindowFrom(Pointer(GDK_WINDOW_XWINDOW(PGtkWidget(PtrUInt(Handle))^.window)));
  6. {$ENDIF}  

does the trick. It does not paint in the control, but on the form, but this is probably a general issue.

Christian

rca

  • Jr. Member
  • **
  • Posts: 67
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #21 on: November 26, 2018, 06:34:31 pm »
@ChristianH

Quote
does the trick. It does not paint in the control, but on the form, but this is probably a general issue.

Or maybe try with:

Code: Pascal  [Select][+][-]
  1. GetXHandle(Handle)

Can you share your code? To test it and complement it as much as possible.

ChristianH

  • New Member
  • *
  • Posts: 46
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #22 on: November 27, 2018, 11:04:06 am »
Thanks,

i honestly just made the changes to provide the code to the original author. Unluckily he does not respond, so i stopped working on his code.

I also have had problems to change the audio stream while playing a file. Maybe somebody has any idea to do so?

Christian

metis

  • Sr. Member
  • ****
  • Posts: 300
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #23 on: November 29, 2018, 12:51:52 pm »
@ChristianH

Quote
Can you share your code? To test it and complement it...
Dito.

Quote
changes to provide the code to the original author...i stopped working on his code
I cannot see any Restriction on somby's Code -> Go on.
You should only mention "R.Sombrowsky info@somby.de" as the Author of the original SourceCode.

Quote
Maybe somebody has any idea to do so?
That's quite difficult w/o any Source.

 :)
Life could be so easy, if there weren't those f*** Details.
My FFmpeg4Lazarus = FFPlay4Laz + FFGrab4Laz + FFInfo4Laz

ChristianH

  • New Member
  • *
  • Posts: 46
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #24 on: December 02, 2018, 05:56:15 pm »
Yes sure,

sorry that i did not found time to continue, but releasing the code to the wild on GitHub seem to be a good idea.

https://github.com/TetrisSQC/StreamPlayer

I also played with the following code:

Code: Pascal  [Select][+][-]
  1. type
  2.    PURLProtocol = ^TURLProtocol;
  3.    PURLContext = ^TURLContext;
  4.  
  5.    TURLContext = record
  6.      av_class: PAVClass;
  7.      prot: PURLProtocol;
  8.      priv_data: pointer;
  9.      filename: PAnsiChar;
  10.      flags: Integer;
  11.      max_packet_size: Integer;
  12.      is_streamed: Integer;
  13.      is_connected: Integer;
  14.      interrupt_callback: TAVIOInterruptCB;
  15.      rw_timeout: Int64;
  16.    end;
  17.  
  18.  
  19.    TURLProtocol = record
  20.     name: PAnsiChar;
  21.     url_open: function(h: PURLContext; url: PAnsiChar; flags: integer)
  22.       : integer; cdecl;
  23.     url_open2: function(h: PURLContext; url: PAnsiChar; flags: integer;
  24.       var options: PAVDictionary): integer; cdecl;
  25.     url_read: function(h: PURLContext; buf: PByte; size: integer)
  26.       : integer; cdecl;
  27.     url_write: function(h: PURLContext; buf: PByte; size: integer)
  28.       : integer; cdecl;
  29.     url_seek: function(h: PURLContext; pos: int64; whence: integer)
  30.       : int64; cdecl;
  31.     url_close: function(h: PURLContext): integer; cdecl;
  32.     next: PURLProtocol;
  33.     url_read_pause: function(h: PURLContext; pause: integer): integer; cdecl;
  34.     url_read_seek: function(h: PURLContext; stream_index: integer;
  35.       timestamp: int64; flags: integer): int64; cdecl;
  36.     url_get_file_handle: function(h: PURLContext): integer; cdecl;
  37.     url_get_multi_file_handle: function(h: PURLContext; var handles: PInteger;
  38.       var numhandles: integer): integer; cdecl;
  39.     url_shutdown: function(h: PURLContext; flags: integer): integer; cdecl;
  40.  
  41.     priv_data_size: integer;
  42.     priv_data_class: PAVClass;
  43.     flags: integer;
  44.     url_check: function(h: PURLContext; mask: integer): integer; cdecl;
  45.   end;
  46.  
  47. function TCustomPlayer.GetShoutcastMeta: string;
  48. var
  49.   V: PAnsiChar;
  50.   Prot: PURLContext;
  51. begin
  52.   V := nil;
  53.   Result := '';
  54.   if (not Assigned(FFormatCtx)) then
  55.     exit;
  56.   if (not Assigned(FFormatCtx^.pb)) then
  57.     exit;
  58.   if not Assigned(FFormatCtx^.pb^.opaque) then
  59.     exit;
  60.   Prot := PURLContext(FFormatCtx^.pb^.opaque);
  61.   if Assigned(Prot) and Assigned(Prot^.priv_data) then
  62.   begin
  63.     av_opt_get(Prot^.priv_data, 'icy_metadata_packet', 0, V);
  64.     if Assigned(V) then
  65.     begin
  66.       Result := V;
  67.       av_free(V);
  68.     end;
  69.   end;
  70. end;

but somehow it crashes, when i try to get the URLContext.

Christian
« Last Edit: December 02, 2018, 06:02:29 pm by ChristianH »

rca

  • Jr. Member
  • **
  • Posts: 67
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #25 on: December 02, 2018, 10:49:37 pm »
@ChristianH

Thanks for sharing with the entire community.

The "SDL2" folder must be added to your github repository to compile your program.

BazCuda

  • Newbie
  • Posts: 1
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #26 on: July 06, 2023, 03:17:50 pm »
Hi all.

A big thank you to Somby for sharing his hard work with us.

I developed a feature-rich media player ("Minimalist Media Player") for Delphi but with minimal window clutter and controls - it's all keyboard and mouse controlled in a borderless window. If you're interested, the Delphi source code and a 64-bit Windows build is available at https://github.com/BazzaCuda/MinimalistMediaPlayer.

Although I'm very pleased with the result it has always irked me that it's built using the Windows Media Player ActiveX control which, on the whole, works very well but it does have some limitations. Since I first wrote it I've wanted to convert it to a more "native"/low-level solution using either SDL2 or FFMpeg, or maybe MPlayer, MfPack or Microsoft Media Foundation - anything in fact that was a lot more robust than being reliant on WMP.

I have never been sure what [these days] constitutes the most up-to-date platform on which to build such a media player for Windows, although I was leaning towards it being FFMpeg-based.

In Somby's work I may have finally found my answer and I'm now considering converting my media player so it's based on Somby's code - he will of course get all due credit in the source code and in my Github repository.

I would welcome any thoughts you have generally about SDL2 and FFMpeg but especially as regards codecs. Clearly, from using my own player as my main media player for a long while now, the Windows Media Player ActiveX control supports a lot of codecs. I have always assumed that FFMpeg probably supports as many codecs as WMP does, if not more, without me needing to install additional codecs manually. Is this true?

Also, is it fair to assume that SDL2 and FFMpeg are likely to keep abreast with video playback development (particularly for Windows) going forward and they're therefore a solid, future-proofed platform on which to base my media player?

Thanks in advance for any thoughts you may have and, again, many thanks to Somby for giving me the possibility to ditch WMP.

regards,
Baz.


 

TinyPortal © 2005-2018