alexmercerind / dart_vlc

Flutter bindings to libVLC.
GNU Lesser General Public License v2.1
510 stars 136 forks source link

Support Desktop Mac OS #14

Closed trunghieuvn closed 3 years ago

trunghieuvn commented 3 years ago

please support desktop mac os thank so much

alexmercerind commented 3 years ago

This plugin only supporting Linux & Windows (at this moment) is actually a technical requirement, because both these operating systems use C++ for platform channels. In future, I plan to make a FFI based binding to the existing dartvlc wrapper, after that we will be able to support nearly all platforms (maybe).

mabDc commented 3 years ago

for another vlc player https://github.com/solid-software/flutter_vlc_player may implement https://github.com/solid-software/flutter_vlc_player/tree/master/flutter_vlc_player_platform_interface to support all platform

alexmercerind commented 3 years ago

@mabDc , that implementation is not based on native C/C++. Aim of this project is to use single codebase to bring media support for all platforms with FFI & nativeports. (And not just Flutter, but console Dart apps too)

With that being said, there is already a lot of work done here (more than that library), we have whole wrapper built, that already supports playback, recording, broadcast & chromecast. This library is not just a "VLC player".

trunghieuvn commented 3 years ago

@alexmercerind you have plan support for mac os desktop? for plan support for mobile (android vs iOS) for future

stuartmorgan commented 3 years ago

This plugin only supporting Linux & Windows (at this moment) is actually a technical requirement, because both these operating systems use C++ for platform channels.

Objective-C is fully interoperable with C and C++.

alexmercerind commented 3 years ago

@stuartmorgan unfortunately I don't have any knowledge of Objective-C at all & I don't have a mac environment to debug project in case I use platform channels. I have to use FFI & just compiling a single dylib might work & I'm not sure about it. Rest whole native code is in dartvlc directory, if someone wanna contribute.

I will be though working at my best to get mac support soon, I also need it for some project soon.

stuartmorgan commented 3 years ago

I was not suggesting that there aren't valid reasons a plugin developer might not support macOS. I was simply pointing out that the specific statement that there is a technical limitation here based on the platform channel language is not accurate. A macOS plugin can trivially call into C++code.

alexmercerind commented 3 years ago

@stuartmorgan okay :pray: !

But, still I don't think it is wrong to call C/C++ a "technical requirement" (atleast for me). This whole wrapper is built somehow without messing with objective-C yet, and additional setup in any case FFI / platform channel is necessary.

Thanks for help.

YukunXia commented 3 years ago

On mac, libvlc can be installed through installing vlc, and here's a list of the related c files.

/Applications/VLC.app/Contents/MacOS/include/vlc/libvlc.h
/Applications/VLC.app/Contents/MacOS/include/vlc/libvlc_dialog.h
/Applications/VLC.app/Contents/MacOS/include/vlc/libvlc_events.h
/Applications/VLC.app/Contents/MacOS/include/vlc/libvlc_media.h
/Applications/VLC.app/Contents/MacOS/include/vlc/libvlc_media_discoverer.h
/Applications/VLC.app/Contents/MacOS/include/vlc/libvlc_media_library.h
/Applications/VLC.app/Contents/MacOS/include/vlc/libvlc_media_list.h
/Applications/VLC.app/Contents/MacOS/include/vlc/libvlc_media_list_player.h
/Applications/VLC.app/Contents/MacOS/include/vlc/libvlc_media_player.h
/Applications/VLC.app/Contents/MacOS/include/vlc/libvlc_renderer_discoverer.h
/Applications/VLC.app/Contents/MacOS/include/vlc/libvlc_version.h
/Applications/VLC.app/Contents/MacOS/include/vlc/libvlc_vlm.h
/Applications/VLC.app/Contents/MacOS/lib/libvlc.5.dylib
/Applications/VLC.app/Contents/MacOS/lib/libvlc.dylib
/Applications/VLC.app/Contents/MacOS/lib/libvlccore.9.dylib
/Applications/VLC.app/Contents/MacOS/lib/libvlccore.dylib

Maybe we can take advantage of these files? I saw you have a script CreateSharedLibrary.sh to generate dart_vlc.so, but that replies on the header file in root/linux/include. If I'm gonna try writing a similar c and cmake program on mac like your root/linux and root/windows folder, how can I do that? Any good tutorial for this?

By the way, I didn't see where the dart_vlc.so or .dll files are stored... Are they generated at runtime?

alexmercerind commented 3 years ago

@YukunXia yeah dart_vlc.dll and respective shared library on Linux is built on runtime using CMake. Other libVLC headers & shared libraries are fetched from videoLAN servers. CreateSharedLibrary.sh is not used anywhere, its just redundant. That ffi directory uses the dartvlc directory C++ code and binds it to the main plugin.

I'm not much aware of macOS build environment, I'll have a look in the morning & possibly guide you. Thankyou.

YukunXia commented 3 years ago

@YukunXia yeah dart_vlc.dll and respective shared library on Linux is built on runtime using CMake. Other libVLC headers & shared libraries are fetched from videoLAN servers. CreateSharedLibrary.sh is not used anywhere, its just redundant. That ffi directory uses the dartvlc directory C++ code and binds it to the main plugin.

I'm not much aware of macOS build environment, I'll have a look in the morning & possibly guide you. Thankyou.

macOS is pretty similar to Linux... Except for some low-level system C code, the high-level C code and config of CMake project normally will be very similar on these two platform. So I think it's technically promising to make your dar_vlc support mac.

Just realize it's 3AM in India now. Have a good night bro.

stuartmorgan commented 3 years ago

macOS is pretty similar to Linux...

The build system for macOS Flutter plugins, which is what this library build is piggybacking on, is extremely different from the Linux and Windows plugin build system.

Except for some low-level system C code, the high-level C code and config of CMake project normally will be very similar on these two platform.

The macOS plugin system is based on Cocoapods, and doesn't use CMake at all.

YukunXia commented 3 years ago

macOS is pretty similar to Linux...

The build system for macOS Flutter plugins, which is what this library build is piggybacking on, is extremely different from the Linux and Windows plugin build system.

Except for some low-level system C code, the high-level C code and config of CMake project normally will be very similar on these two platform.

The macOS plugin system is based on Cocoapods, and doesn't use CMake at all.

Yeah, you are right. So is there any way to generate libdartvlc.dylib with libvlc.dylib for mac? Or is that even the right track to follow?

I was trying to generate a libdartvlc.dylib and use that like .so and .dll on linux and windows:

    if (Platform.isWindows) {
      String directory = Platform.resolvedExecutable
          .split('\\')
          .sublist(0, Platform.resolvedExecutable.split('\\').length - 1)
          .join('\\');
      FFI.DartVLC.initialize(directory + '\\' + 'dart_vlc.dll');
    }
    if (Platform.isLinux) {
      String directory = Platform.resolvedExecutable
          .split('/')
          .sublist(0, Platform.resolvedExecutable.split('/').length - 1)
          .join('/');
      FFI.DartVLC.initialize(directory + '/lib/' + 'libdartvlc.so');
    }

But that track could be completely wrong...

YukunXia commented 3 years ago

macOS is pretty similar to Linux...

The build system for macOS Flutter plugins, which is what this library build is piggybacking on, is extremely different from the Linux and Windows plugin build system.

Except for some low-level system C code, the high-level C code and config of CMake project normally will be very similar on these two platform.

The macOS plugin system is based on Cocoapods, and doesn't use CMake at all.

I once watched this video https://www.youtube.com/watch?v=2MMK7YoFgaA, which uses ffi and dylib files to call C functions from dart. That video shows we can generate dynamic library files in advance and use them later, but the dart_vlc generates that at runtime. That was where I got lost : (

alexmercerind commented 3 years ago

All I need to do, is to get my dynamic library compiled for mac. Rest should be fine. I don't have literally any experience in Objective C or mac development environment.

YukunXia commented 3 years ago

All I need to do, is to get my dynamic library compiled for mac. Rest should be fine. I don't have literally any experience in Objective C or mac development environment.

I think theoretically that's doable. Not sure if that's a good practice though. I just learned that your dart_vlc is a plugin concept in flutter (sorry, I'm pretty new to the front-end tech stack). According to this page https://flutter.dev/docs/development/packages-and-plugins/developing-packages, I can add macos: pluginClass: DartVlcPlugin to the end of pubspec.yaml, and run flutter create --template=plugin --platforms=macos . at dart_vlc's root. I did that, but obviously, I didn't get cmake stuff. Instead, a dart_vlc.podspec and DartVlcPlugin.swift were generated. Perhaps that means the cmake way is a dead-end, and I'm thinking if including dylib/so/dll in a flutter package is recommended by flutter.

alexmercerind commented 3 years ago

@YukunXia this project actually isn't a plugin either. It's an FFI binding now. You may just follow the FFI procedure. This does not use platform channel at all.

Just in case you're interested. Thanks for having a look.

YukunXia commented 3 years ago

@YukunXia this project actually isn't a plugin either. It's an FFI binding now. You may just follow the FFI procedure. This does not use platform channel at all.

Just in case you're interested. Thanks for having a look.

@alexmercerind It'd be interesting to see. I haven't seen any good tutorial on bridging c/c++ libraries to dart.

stuartmorgan commented 3 years ago

You may just follow the FFI procedure.

There is no mechanism for building native code from source as part of a package other than by making your package a Flutter plugin and using the plugin build system. Like you are doing on Windows and Linux. There is no "FFI procedure" for this.

YukunXia commented 3 years ago

@alexmercerind I'm still a little bit confused about how you generate and link the dynamic link libraries. Happened to come across this project: https://github.com/Sunbreak/cronet_flutter/tree/master/macos. It supports all platforms and under each desktop platform's folder, there's a dynamic link file. For macos, it includes all c files and dart API, even if they are already placed under the common folder. I didn't compare the c files line by line, but from the names, they look identical to the ones under common. There's some minor modifications to the podspec files, but the swift file looks untouched.

By default, the podspec looks like this:

#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint dart_vlc.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
  s.name             = 'dart_vlc'
  s.version          = '0.0.1'
  s.summary          = 'A new flutter plugin project.'
  s.description      = <<-DESC
A new flutter plugin project.
                       DESC
  s.homepage         = 'http://example.com'
  s.license          = { :file => '../LICENSE' }
  s.author           = { 'Your Company' => 'email@example.com' }
  s.source           = { :path => '.' }
  s.source_files     = 'Classes/**/*'
  s.dependency 'FlutterMacOS'

  s.platform = :osx, '10.11'
  s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
  s.swift_version = '5.0'
end

And that podspec has the following content.

#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint cronet_flutter.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
  s.name             = 'cronet_flutter'
  s.version          = '0.0.1'
  s.summary          = 'A new flutter plugin project.'
  s.description      = <<-DESC
A new flutter plugin project.
                       DESC
  s.homepage         = 'http://example.com'
  s.license          = { :file => '../LICENSE' }
  s.author           = { 'Your Company' => 'email@example.com' }
  s.source           = { :path => '.' }
  s.source_files     = 'Classes/**/*'
  s.public_header_files = 'Classes/**/*.h'
  s.dependency 'FlutterMacOS'

  s.vendored_libraries = 'libcronet.86.0.4240.198.dylib'

  s.platform = :osx, '10.11'
  s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
  s.swift_version = '5.0'

  # Fix symbol not found when without use_framework!
  s.user_target_xcconfig = { 'OTHER_LDFLAGS' => '-ObjC -all_load' }

  # including system libraries
  s.libraries = 'c++'
end

Naively thinking, you may do similar stuff. I wanna try, but the obstacle is that your dynamic library files are generated at runtime.

YukunXia commented 3 years ago

Another one https://github.com/google/cronet.dart/blob/main/src/CMakeLists.txt claims to support all platforms, but their source code is organized in a different way. Only the src folder (c wrapper and cmakelists.txt) and the thrid_party folder (c files), I think, are related to the c side. The cmakelists.txt has platform-dependent code inside, and has this line add_library(${PLUGIN_NAME} SHARED. There's no compiled dynamic library there...

alexmercerind commented 3 years ago

@YukunXia indeed this project in specific is very very different from others at this point. It's because I'm not using original plugin template, but making my own shared library to look for functions. I'll figure out a way, all I need to do is to compile this file for macOS.

I'll look for support from libVLC community. I don't have mac, but I'll try to setup a VM.

alexmercerind commented 3 years ago

Even if I won't be able to figure out automatic copying of shared libs, this FFI approach still can be used. (Would ask users to copy the files themselves, afterall many plugins require additional setup). (Afterall the work in this repository is also not "officially accepted way of making plugins", because I'm not using MethodChannel interface at all).

I have no idea what cocoapods & all is. If someone wants to go with the classic platform channel approach for mac & wanna make a PR, I'm okay with it but one has to do a lot of stuff.

namniav commented 3 years ago

I managed to build the example app for macOS by:

However, the example app crashed as soon as it launched because libvlc_new returns a NULL pointer and VLCPP aborts the program immediately:

libc++abi: terminating with uncaught exception of type std::runtime_error: Wrapping a NULL instance

The error occured in libvlc_InternalInit, but I can't find the actual reason yet, because almost debug symbols are wiped out of the prebuild binary of VLC APP. May be better if I can build my own libvlc on macOS.

Btw, there's a tiny memory leak here.

alexmercerind commented 3 years ago

@namniav that's really really good to hear. 👍

I have no idea about that exception however.

You could try out reaching out libvlcpp & libvlc developers at libVLC discord server, I'm also there (alexmercerind#3898). Let me know here, if you are able to fix this runtime error, possibly libVLC developers might help you out find out the cause of this.

You may offer this project a pull request with your requested changes & required additional documentation for macOS. I don't have mac device to help you out along this however.

Btw, there's a tiny memory leak here.

Thankyou for the info.

alexmercerind commented 3 years ago

A big thanks to @namniav, initial macOS support will be soon added.

A PR is made by them at #105. Looking forward to their great work on this issue.

alexmercerind commented 3 years ago

This is up on master now. For texture support, there is another issue opened.