/***************************************************************************** * iosvlc.m: iOS specific development main executable for VLC media player ***************************************************************************** * Copyright (C) 2020 Videolabs * * Authors: Marvin Scholz * Alexandre Janniaux * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ #ifdef HAVE_CONFIG_H # include "config.h" #endif #import #include #include #include #include #include @interface AppDelegate : UIResponder { @public libvlc_instance_t *_libvlc; UIWindow *window; UIView *subview; #if TARGET_OS_IOS UIPinchGestureRecognizer *_pinchRecognizer; #endif CGRect _pinchRect; CGPoint _pinchOrigin; CGPoint _pinchPreviousCenter; } @end @implementation AppDelegate #if TARGET_OS_IOS - (void)pinchRecognized:(UIPinchGestureRecognizer *)pinchRecognizer { UIGestureRecognizerState state = [pinchRecognizer state]; switch (state) { case UIGestureRecognizerStateBegan: _pinchRect = [subview frame]; _pinchOrigin = [pinchRecognizer locationInView:nil]; _pinchPreviousCenter = [subview center]; return; case UIGestureRecognizerStateEnded: return; case UIGestureRecognizerStateChanged: break; default: return; } CGFloat scale = pinchRecognizer.scale; CGRect viewBounds = _pinchRect; if (scale >= 1.0 && (viewBounds.size.width == 0 || viewBounds.size.height == 0)) viewBounds.size.width = viewBounds.size.height = 1; viewBounds.size.width *= scale; viewBounds.size.height *= scale; subview.frame = viewBounds; CGPoint newPosition = [pinchRecognizer locationInView:nil]; subview.center = CGPointMake( _pinchPreviousCenter.x + newPosition.x - _pinchOrigin.x, _pinchPreviousCenter.y + newPosition.y - _pinchOrigin.y); } #endif /* Called after application launch */ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { /* Set VLC_PLUGIN_PATH for dynamic loading */ NSString *pluginsDirectory = [[NSBundle mainBundle] privateFrameworksPath]; setenv("VLC_PLUGIN_PATH", [pluginsDirectory UTF8String], 1); /* Store startup arguments to forward them to libvlc */ NSArray *arguments = [[NSProcessInfo processInfo] arguments]; unsigned vlc_argc = [arguments count]; const char **vlc_argv = malloc(vlc_argc * sizeof *vlc_argv); if (vlc_argv == NULL) return NO; for (unsigned i = 0; i < vlc_argc; i++) vlc_argv[i] = [[arguments objectAtIndex:i] UTF8String]; /* Initialize libVLC */ _libvlc = libvlc_new(vlc_argc, (const char * const*)vlc_argv); free(vlc_argv); if (_libvlc == NULL) return NO; /* Initialize main window */ window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]; window.rootViewController = [UIViewController alloc]; window.backgroundColor = [UIColor whiteColor]; subview = [[UIView alloc] initWithFrame:window.bounds]; subview.backgroundColor = [UIColor blueColor]; [window addSubview:subview]; [window makeKeyAndVisible]; #if TARGET_OS_IOS _pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchRecognized:)]; [window addGestureRecognizer:_pinchRecognizer]; #endif /* Start glue interface, see code below */ libvlc_add_intf(_libvlc, "ios_interface,none"); /* Start parsing arguments and eventual playback */ libvlc_playlist_play(_libvlc, -1, 0, NULL); return YES; } @end int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } /* Glue interface code, define drawable-nsobject for display module */ static int Open(vlc_object_t *obj) { AppDelegate *d = (AppDelegate *)[[UIApplication sharedApplication] delegate]; assert(d != nil && d->subview != nil); var_SetAddress(obj->obj.libvlc, "drawable-nsobject", (__bridge void *)d->subview); return VLC_SUCCESS; } #define MODULE_NAME ios_interface #define MODULE_STRING "ios_interface" vlc_module_begin() set_capability("interface", 0) set_callbacks(Open, NULL) vlc_module_end() /* Inject the glue interface as a static module */ typedef int (*vlc_plugin_cb)(vlc_set_cb, void*); __attribute__((visibility("default"))) vlc_plugin_cb vlc_static_modules[] = { vlc_entry__ios_interface, NULL };