QuickTime video player for Cocoa

Mac OSX specific forum
Niffo
Enthusiast
Enthusiast
Posts: 500
Joined: Tue Jan 31, 2006 9:43 am
Location: France

QuickTime video player for Cocoa

Post by Niffo »

Does someone knows how to do this working for Cocoa ?
http://www.purebasic.fr/english/viewtop ... 52#p316294
CreateMovieControl seems to be a Carbon only API
Niffo
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: QuickTime video player for Cocoa

Post by Danilo »

Use QTMovie with QTMovieView:

Code: Select all

Import "/System/Library/Frameworks/QTKit.framework/QTKit"
EndImport
OpenWindow(0, 5, 5, 800, 600, "QTMovieView",#PB_Window_SystemMenu|#PB_Window_Invisible)
    
movie.s = "/Users/danilo/Movies/myMovie.mov"
movie.s = "/Users/danilo/Movies/myMovie.mp4"
movie.s = OpenFileRequester("Open Movie",GetHomeDirectory()+"Movies/","*.*",0)

CocoaMessage(@qtMovieView,0,"QTMovieView alloc")
CocoaMessage(@qtMovie,0,"QTMovie movieWithFile:$",@movie)
If qtMovieView
    rect.NSRect
    rect\origin\x = 10
    rect\origin\y = 10
    rect\size\width = 780
    rect\size\height = 580
    CocoaMessage(0,qtMovieView,"initWithFrame:@",@rect)
    CocoaMessage(0,qtMovieView,"setPreservesAspectRatio:",#YES)
    CocoaMessage(0,qtMovieView,"setFillColor:",
                 CocoaMessage(0,0,"NSColor whiteColor"))
    CocoaMessage(0,qtMovieView,"setControllerVisible:",#YES)
    CocoaMessage(0,qtMovieView,"setZoomButtonsVisible:",#YES)
    CocoaMessage(0,qtMovieView,"setVolumeButtonVisible:",#YES)
    
    view = CocoaMessage(0,WindowID(0),"contentView")
    If view
        CocoaMessage(0,view,"addSubview:",qtMovieView)
    EndIf
    
    If qtMovie
        CocoaMessage(0,qtMovieView,"setMovie:",qtMovie)
        ;CocoaMessage(0,qtMovieView,"play:",0)
        ;CocoaMessage(0,qtMovieView,"pause:",0)
        ;CocoaMessage(0,qtMovieView,"gotoBeginning:",0)
        ;CocoaMessage(0,qtMovieView,"gotoEnd:",0)
        CocoaMessage(0,qtMovie,"autoplay")
        ;CocoaMessage(0,qtMovie,"play")
        ;CocoaMessage(0,qtMovie,"stop")
        ;CocoaMessage(0,qtMovie,"gotoBeginning")
        ;CocoaMessage(0,qtMovie,"gotoEnd")
    Else
        Debug "qtMovie = 0"
    EndIf
Else
    Debug "qtMovieView = 0"
EndIf
HideWindow(0,#False)

Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
Niffo
Enthusiast
Enthusiast
Posts: 500
Joined: Tue Jan 31, 2006 9:43 am
Location: France

Re: QuickTime video player for Cocoa

Post by Niffo »

Thank you VERY much for this sample code Danilo !

It seems QTMovie (who is based on QuickTime 7) is deprecated since OSX 10.9 (Mavericks).
https://developer.apple.com/library/mac ... rence.html

Do you know what Cocoa object we are supposed to use now ?


Regards.
Niffo
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: QuickTime video player for Cocoa

Post by Danilo »

Niffo wrote:Do you know what Cocoa object we are supposed to use now ?
Maybe AV Foundation?

- Technical Note TN2300 - Transitioning QTKit Code to AV Foundation

- OS X Mavericks v10.9 - Framework-Level Features
New Frameworks
The following frameworks have been added in OS X v10.9:
  • AV Kit (AVKit.framework). AV Kit is a modern API for incorporating media playback capabilities into apps. AV Kit provides view-level services for media playback, complete with user controls, chapter navigation, and support for subtitles and closed captioning. Built on the most modern OS X media technology, AV Kit is an ideal starting point for developers looking to transition their QuickTime-based applications to AV Foundation.
[...]

Deprecated Frameworks

The QuickTime and QTKit frameworks are superseded by AV Kit and AV Foundation.
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: QuickTime video player for Cocoa

Post by fsw »

Was anyone successful in using AVKit/AVFoundation with PureBasic?

I've tried it with Objective C (nibless without Xcode) in the hope I could figure this out and port it over to PureBasic.
But to no avail, I can show the AV view with play button, time slider and time (default AVPlayer configuration) but the video never plays.
If the player is forced to play (programmatically) the play button changes to pause, but again, the video is never played.

Thanks

BTW: All working code I found was with a NIB or Storyboard (and Xcode...)

I am to provide the public with beneficial shocks.
Alfred Hitshock
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: QuickTime video player for Cocoa

Post by wilbert »

fsw wrote:Was anyone successful in using AVKit/AVFoundation with PureBasic?
I just tried it and it seems to work fine on my computer. :)
Resizing the window works fine.
Even a custom popup menu to change the player style seems to be working.

I don't know if the video link keeps working as it's just something I found online, not something I'm hosting.

Code: Select all

ImportC "-framework AVKit" : EndImport

Procedure AVPlayerGadget(Gadget, x, y, Width, Height, Flags = 0)
  Protected Result, ContainerID, Viewer, Frame.NSRect
  Result = ContainerGadget(Gadget, x, y, Width, Height, Flags)
  CloseGadgetList()
  If Gadget = #PB_Any
    ContainerID = GadgetID(Result)
  Else
    ContainerID = GadgetID(Gadget)
  EndIf
  Viewer = CocoaMessage(0, CocoaMessage(0, 0, "AVPlayerView alloc"), "initWithFrame:@", @Frame)
  CocoaMessage(0, ContainerID, "setContentView:", Viewer)
  CocoaMessage(0, Viewer, "release")
  ProcedureReturn Result
EndProcedure

Procedure AVPlayerGadget_GetPlayerView(Gadget)
  Protected Result
  If IsGadget(Gadget) And GadgetType(Gadget) = #PB_GadgetType_Container
    Result = CocoaMessage(0, GadgetID(Gadget), "contentView")
  EndIf
  ProcedureReturn Result
EndProcedure



; >>> Main code <<<

Enumeration
  #AVPlayerViewControlsStyleNone
  #AVPlayerViewControlsStyleInline
  #AVPlayerViewControlsStyleFloating
  #AVPlayerViewControlsStyleMinimal
EndEnumeration


Procedure SizeWindowHandler()
  ResizeGadget(0, #PB_Ignore, #PB_Ignore, WindowWidth(EventWindow())-20, WindowHeight(EventWindow())-20)
EndProcedure

Procedure Player_SetURL(Player, URL.s)
  Protected NSURL, Item
  NSURL = CocoaMessage(0, 0, "NSURL URLWithString:$", @URL)
  Item = CocoaMessage(0, 0, "AVPlayerItem playerItemWithURL:", NSURL)
  CocoaMessage(0, Player, "replaceCurrentItemWithPlayerItem:", Item)  
EndProcedure

Procedure Player_SetFile(Player, Filename.s)
  Protected NSURL, Item
  NSURL = CocoaMessage(0, 0, "NSURL fileURLWithPath:$", @Filename)
  Item = CocoaMessage(0, 0, "AVPlayerItem playerItemWithURL:", NSURL)
  CocoaMessage(0, Player, "replaceCurrentItemWithPlayerItem:", Item)  
EndProcedure

  
If OpenWindow(0, 0, 0, 620, 420, "AVPlayerView example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
  WindowBounds(0, 320, 200, #PB_Ignore, #PB_Ignore)
  
  ; Create custom popup menu for AVPlayerView
  CreatePopupMenu(0)
  MenuItem(1, "Inline menu style")
  MenuItem(2, "Floating menu style")
  MenuBar()
  MenuItem(3, "Movie 1")
  MenuItem(4, "Movie 2")
  MenuItem(5, "BBC Radio 1")
  NSMenu = CocoaMessage(0, MenuID(0), "objectAtIndex:", 0)
  
  ; Init AVPlayerView
  AVPlayerGadget(0, 10, 10, 600, 400, #PB_Container_Flat)
  PlayerView = AVPlayerGadget_GetPlayerView(0)
  CocoaMessage(0, PlayerView, "setControlsStyle:", #AVPlayerViewControlsStyleFloating)
  CocoaMessage(0, PlayerView, "setActionPopUpButtonMenu:", NSMenu)
  
  ; Set content
  Player = CocoaMessage(0, 0, "AVPlayer new")
  CocoaMessage(0, PlayerView, "setPlayer:", Player)
  Player_SetURL(Player, "http://download.blender.org/peach/trailer/trailer_480p.mov")
  
  ; Bind resize event
  BindEvent(#PB_Event_SizeWindow, @SizeWindowHandler())
  
  ; Handle popup menu events
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            CocoaMessage(0, PlayerView, "setControlsStyle:", #AVPlayerViewControlsStyleInline)
          Case 2
            CocoaMessage(0, PlayerView, "setControlsStyle:", #AVPlayerViewControlsStyleFloating)
          Case 3
            Player_SetURL(Player, "http://download.blender.org/peach/trailer/trailer_480p.mov")
          Case 4
            Player_SetURL(Player, "http://www.html5videoplayer.net/videos/toystory.mp4")
          Case 5
            Player_SetURL(Player, "http://www.listenlive.eu/bbcradio1.m3u")
        EndSelect  
    EndSelect  
  Until Event = #PB_Event_CloseWindow
  
EndIf
Last edited by wilbert on Wed Jun 28, 2017 3:25 pm, edited 1 time in total.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: QuickTime video player for Cocoa

Post by fsw »

Nice.

However not all media is playable in this version (like local MP4).
Whereas with Xcode compiled apps the MP4's are played...

Technical question:
I thought AVPlayerView is derived from NSView therefore it should be possible to make a subView for a window out of it.
But you put a container as the AVPlayerView's parent (with setContentView) and even release the AVPlayerView and are still able to use the container's conrentView...
What kind of magic is going on here?

I appreciate any info.

Thanks

I am to provide the public with beneficial shocks.
Alfred Hitshock
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: QuickTime video player for Cocoa

Post by wilbert »

fsw wrote:not all media is playable in this version (like local MP4).
Whereas with Xcode compiled apps the MP4's are played...
I updated the code above.
It has an additional method now to use a local mp4 file.
fsw wrote:I thought AVPlayerView is derived from NSView therefore it should be possible to make a subView for a window out of it.
But you put a container as the AVPlayerView's parent (with setContentView) and even release the AVPlayerView and are still able to use the container's conrentView...
What kind of magic is going on here?
AVPlayerView is indeed a subclass of NSView. You could also add it to a window directly.
The reason why I used a ContainerGadget is because it makes it a bit easier to interact with PB commands to hide or resize it.
When AVPlayerView is added to the container with setContentView, the container retains the object so it can be safely released.
Retain and release are a counting system and only when the counter hits zero, the object is destroyed.
So in this case, I leave it up to the ContainerGadget. If the container gadget is released, it should no longer retain the AVPlayerView object so that will be released also (as far as I understand :wink: ).
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: QuickTime video player for Cocoa

Post by fsw »

Thank you Wilbert!

Awesome work!

I am to provide the public with beneficial shocks.
Alfred Hitshock
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: QuickTime video player for Cocoa

Post by fsw »

Found out why my Objective C code didn't work:

Using this Objective C code:

Code: Select all

    // AVPlayer
    NSRect rect = ([window frame]);
    NSBox * container = [[NSBox alloc] initWithFrame:rect];
    AVPlayerView * pView = [[AVPlayerView alloc] initWithFrame:rect];
    [container setContentView:pView];
    [pView release];
    [[window contentView] addSubview:container];
    AVPlayerView * playerView = [container contentView];
    [playerView setControlsStyle:AVPlayerViewControlsStyleFloating];
     
    AVPlayer * player = [AVPlayer new];// retain];
    [playerView setPlayer:player];

    //NSURL * contentURL = [NSURL  URLWithString: @"http://www.html5videoplayer.net/videos/toystory.mp4"];
    NSURL * contentURL = [NSURL URLWithString: @"http://download.blender.org/peach/trailer/trailer_480p.mov"];

    AVPlayerItem * myItem = [AVPlayerItem playerItemWithURL:contentURL];
    [player replaceCurrentItemWithPlayerItem:myItem];
    // end AVPlayer
Which is the Objective C equivalent of your code it works, IF

Code: Select all

[NSApp run];
is used in the Objective C program main function.

If I use this:

Code: Select all

NSApplicationMain(argc, (const char **) argv);
in the main function it doesn't work.
There is always the "Media not Playable" icon in the center of the AVPlayer.

(BTW: As soon as NSApplicationMain is used a program.app file with the info.plist file and the program needs to be created)

The question now is:
How can the AVPlayer code be made to work on programs that use:

Code: Select all

NSApplicationMain(argc, (const char **) argv);
:?:

This is an important question because remember PureBasic 5.6 compiled programs do not work reliably on a late 2016 MacBook Pro.
They crash on different occasions.

Now the fun part: :mrgreen:
In the process of getting in to the bottom of this I found out that on 2016 MacBook Pros programs do not crash if they use:

Code: Select all

NSApplicationMain(argc, (const char **) argv);
8)

However, when

Code: Select all

NSApplicationMain(argc, (const char **) argv);
is used the Objective C code posted above will not work!
There is always the "Media not Playable" icon in the center of the AVPlayer.

This also tells me that all programs generated by PureBasic use:

Code: Select all

[NSApp run];
in their main function, otherwise they would work on my 2016 MacBook Pro.
:evil:

How can the AVPlayer code be made to work on programs that use NSApplicationMain :?:
:cry:

I am to provide the public with beneficial shocks.
Alfred Hitshock
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: QuickTime video player for Cocoa

Post by wilbert »

NSApplicationMain requires a nib file and PureBasic doesn't use a nib file.
https://www.cocoawithlove.com/2009/01/d ... on-by.html
You can google something like nibless cocoa to find more information.

Some things XCode takes care of, PureBasic has to do manually.
Maybe the things that are handled automatically by XCode have changed and something additional is needed; I don't know :(
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: QuickTime video player for Cocoa

Post by fsw »

wilbert wrote:NSApplicationMain requires a nib file and PureBasic doesn't use a nib file.
https://www.cocoawithlove.com/2009/01/d ... on-by.html
You can google something like nibless cocoa to find more information.

Some things XCode takes care of, PureBasic has to do manually.
Maybe the things that are handled automatically by XCode have changed and something additional is needed; I don't know :(
Do you have a link where it says that NSApplicationMain needs a nib?

I have lots of NIBless Objective C code with NSApplicationMain and it works just fine.
The AVPlayer object is the first I've encountered.

I am to provide the public with beneficial shocks.
Alfred Hitshock
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: QuickTime video player for Cocoa

Post by wilbert »

https://developer.apple.com/documentati ... guage=objc
The main() function Xcode creates begins by calling a function named NSApplicationMain(), which is functionally similar to the following:

Code: Select all

void NSApplicationMain(int argc, char *argv[]) {
    [NSApplication sharedApplication];
    [NSBundle loadNibNamed:@"myMain" owner:NSApp];
    [NSApp run];
}
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: QuickTime video player for Cocoa

Post by fsw »

Thank you Wilbert.
I've placed some test code in:
http://www.purebasic.fr/english/viewtop ... &start=15
Not sure how valuable it is if I'm the only one with a 2016 MacBook Pro (and one of deseven's customer)

Thanks.

I am to provide the public with beneficial shocks.
Alfred Hitshock
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: QuickTime video player for Cocoa

Post by wilbert »

fsw wrote:Not sure how valuable it is if I'm the only one with a 2016 MacBook Pro (and one of deseven's customer)
I hope someone can help you with it.
All I can do is use the onscreen touch bar emulation Xcode offers.
When I enable that and run my PureBasic example code, I can see AVPlayer makes use of the touch bar.

Image

Maybe this has to do with the problems :?
Windows (x64)
Raspberry Pi OS (Arm64)
Post Reply