rip out media_kit, use better_player and audioplayers
This also let us rip out cocoapods stuff. Needs testing on Windows, MacOS, and ideally, iOS.
This commit is contained in:
parent
161d39322c
commit
37a2c150f3
28 changed files with 375 additions and 604 deletions
11
.github/workflows/windows.yml
vendored
11
.github/workflows/windows.yml
vendored
|
|
@ -45,6 +45,17 @@ jobs:
|
|||
flutter pub run build_runner build
|
||||
flutter build windows --dart-define=GIT_COMMIT=${{ github.sha }}
|
||||
|
||||
# better_player plays videos with libmpv, but doesn't bundle it
|
||||
- name: Download libmpv
|
||||
shell: powershell
|
||||
run: |
|
||||
$archive = "$env:RUNNER_TEMP\mpv.7z"
|
||||
Invoke-WebRequest "https://github.com/shinchiro/mpv-winbuild-cmake/releases/download/20261021/mpv-dev-x86_64-20261021-git-e471496c56.7z" -OutFile $archive
|
||||
if ((Get-FileHash $archive -Algorithm SHA256).Hash -ne "efc719eff3dc5954b4a5efc800632808bcec01cc9034940dd14e5eb7fe9ea633") {
|
||||
throw "libmpv checksum mismatch"
|
||||
}
|
||||
7z e $archive libmpv-2.dll -obuild/windows/x64/runner/Release
|
||||
|
||||
- name: Copy MinGW runtime DLLs
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ This installs Nexus system-wide. With `enableNotifications`, it also installs KU
|
|||
#### Linux
|
||||
|
||||
- On NixOS: Either use direnv and `direnv allow`, or `nix develop`
|
||||
- On other distros: Install Flutter, Go, Git, Libclang, Libass, MPV, and Glibc. Do not use any Snap packages, they cause various compilation issues.
|
||||
- On other distros: Install Flutter, Go, Git, Libclang, MPV, GStreamer (with its base, good and libav plugins), and Glibc. Do not use any Snap packages, they cause various compilation issues.
|
||||
|
||||
#### Windows
|
||||
|
||||
|
|
@ -83,12 +83,11 @@ You will need:
|
|||
|
||||
- Flutter
|
||||
- Git
|
||||
- Libass
|
||||
- MPV
|
||||
- Go
|
||||
- Visual Studio 2022 (Desktop development with C++)
|
||||
- [MSYS2/MinGW-w64 GCC](https://www.msys2.org/) (for CGO)
|
||||
- [LLVM/Clang + libclang](https://clang.llvm.org/get_started.html) (for `ffigen`)
|
||||
- `libmpv-2.dll`, for playing videos, next to `nexus.exe` (CI uses a build from [mpv-winbuild-cmake](https://github.com/shinchiro/mpv-winbuild-cmake/releases))
|
||||
|
||||
On Windows, make sure these are available in your shell `PATH`:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +1 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
|
|
|
|||
|
|
@ -1,2 +1 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
|
|
|
|||
43
ios/Podfile
43
ios/Podfile
|
|
@ -1,43 +0,0 @@
|
|||
# Uncomment this line to define a global platform for your project
|
||||
# platform :ios, '13.0'
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
|
||||
project 'Runner', {
|
||||
'Debug' => :debug,
|
||||
'Profile' => :release,
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||
end
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
|
||||
end
|
||||
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_ios_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
|
||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||
target 'RunnerTests' do
|
||||
inherit! :search_paths
|
||||
end
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_ios_build_settings(target)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
PODS:
|
||||
- Flutter (1.0.0)
|
||||
- media_kit_libs_ios_video (1.0.4):
|
||||
- Flutter
|
||||
- media_kit_video (0.0.1):
|
||||
- Flutter
|
||||
|
||||
DEPENDENCIES:
|
||||
- Flutter (from `Flutter`)
|
||||
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
|
||||
- media_kit_video (from `.symlinks/plugins/media_kit_video/ios`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
media_kit_libs_ios_video:
|
||||
:path: ".symlinks/plugins/media_kit_libs_ios_video/ios"
|
||||
media_kit_video:
|
||||
:path: ".symlinks/plugins/media_kit_video/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
|
||||
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
|
||||
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
|
||||
|
||||
PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e
|
||||
|
||||
COCOAPODS: 1.17.0
|
||||
|
|
@ -8,13 +8,11 @@
|
|||
|
||||
/* Begin PBXBuildFile section */
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||
2ADFEE6C745FFB2100CC9AFD /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8156A45F510382D558AED93A /* Pods_RunnerTests.framework */; };
|
||||
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||
7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */; };
|
||||
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; };
|
||||
88D55A5F1C7625122EBEE29D /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 82F9A3759658343C81A0EA4C /* Pods_Runner.framework */; };
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||
|
|
@ -46,19 +44,14 @@
|
|||
/* Begin PBXFileReference section */
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
22DE4310DAFBE211CDF700B1 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
|
||||
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
363A89F6FA09BCCBDED440CE /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||
63516CF65A79A5DDDE64B0D1 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
|
||||
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = "<group>"; };
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||
8156A45F510382D558AED93A /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
82F9A3759658343C81A0EA4C /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
||||
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
|
|
@ -66,9 +59,6 @@
|
|||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
AEB96D8976BD46D6860C7041 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
B8B599FDB72E4713FB7B5A44 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
FE5E4162842555A83F8A7FD7 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
|
@ -76,7 +66,6 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2ADFEE6C745FFB2100CC9AFD /* Pods_RunnerTests.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -85,27 +74,12 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */,
|
||||
88D55A5F1C7625122EBEE29D /* Pods_Runner.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
1CFFAE23B502BCCEB2B191A3 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
AEB96D8976BD46D6860C7041 /* Pods-Runner.debug.xcconfig */,
|
||||
363A89F6FA09BCCBDED440CE /* Pods-Runner.release.xcconfig */,
|
||||
22DE4310DAFBE211CDF700B1 /* Pods-Runner.profile.xcconfig */,
|
||||
B8B599FDB72E4713FB7B5A44 /* Pods-RunnerTests.debug.xcconfig */,
|
||||
FE5E4162842555A83F8A7FD7 /* Pods-RunnerTests.release.xcconfig */,
|
||||
63516CF65A79A5DDDE64B0D1 /* Pods-RunnerTests.profile.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
331C8082294A63A400263BE5 /* RunnerTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -114,15 +88,6 @@
|
|||
path = RunnerTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
594EB1F65336CF9C7958F6FA /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
82F9A3759658343C81A0EA4C /* Pods_Runner.framework */,
|
||||
8156A45F510382D558AED93A /* Pods_RunnerTests.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -142,8 +107,6 @@
|
|||
97C146F01CF9000F007C117D /* Runner */,
|
||||
97C146EF1CF9000F007C117D /* Products */,
|
||||
331C8082294A63A400263BE5 /* RunnerTests */,
|
||||
1CFFAE23B502BCCEB2B191A3 /* Pods */,
|
||||
594EB1F65336CF9C7958F6FA /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
|
|
@ -179,7 +142,6 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
|
||||
buildPhases = (
|
||||
EE82EC529EB6C0F1FA480659 /* [CP] Check Pods Manifest.lock */,
|
||||
331C807D294A63A400263BE5 /* Sources */,
|
||||
331C807F294A63A400263BE5 /* Resources */,
|
||||
8C0A36760DA8B873D8F6DDCE /* Frameworks */,
|
||||
|
|
@ -198,14 +160,12 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
0830C6758DA3ECA81FB12386 /* [CP] Check Pods Manifest.lock */,
|
||||
9740EEB61CF901F6004384FC /* Run Script */,
|
||||
97C146EA1CF9000F007C117D /* Sources */,
|
||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||
97C146EC1CF9000F007C117D /* Resources */,
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
1D165FDFB9D0D939B041966D /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
|
@ -283,45 +243,6 @@
|
|||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
0830C6758DA3ECA81FB12386 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
1D165FDFB9D0D939B041966D /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
|
|
@ -353,28 +274,6 @@
|
|||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
||||
};
|
||||
EE82EC529EB6C0F1FA480659 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
|
|
@ -502,7 +401,6 @@
|
|||
};
|
||||
331C8088294A63A400263BE5 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = B8B599FDB72E4713FB7B5A44 /* Pods-RunnerTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
|
|
@ -520,7 +418,6 @@
|
|||
};
|
||||
331C8089294A63A400263BE5 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = FE5E4162842555A83F8A7FD7 /* Pods-RunnerTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
|
|
@ -536,7 +433,6 @@
|
|||
};
|
||||
331C808A294A63A400263BE5 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 63516CF65A79A5DDDE64B0D1 /* Pods-RunnerTests.profile.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
|
|
|
|||
3
ios/Runner.xcworkspace/contents.xcworkspacedata
generated
3
ios/Runner.xcworkspace/contents.xcworkspacedata
generated
|
|
@ -4,7 +4,4 @@
|
|||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import "package:dynamic_color/dynamic_color.dart";
|
|||
import "package:flutter/foundation.dart";
|
||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:material_emoji_picker/material_emoji_picker.dart";
|
||||
import "package:media_kit/media_kit.dart";
|
||||
import "package:nexus/controllers/active_account.dart";
|
||||
import "package:nexus/controllers/client.dart";
|
||||
import "package:nexus/controllers/client_state.dart";
|
||||
|
|
@ -65,7 +64,6 @@ void showError(Object error, [StackTrace? stackTrace]) {
|
|||
|
||||
void main(List<String> args) async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
MediaKit.ensureInitialized();
|
||||
|
||||
LicenseRegistry.addLicense(() => .fromIterable(fontLicenses));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import "dart:async";
|
||||
|
||||
import "package:audioplayers/audioplayers.dart" as audioplayers;
|
||||
import "package:material_ui/material_ui.dart";
|
||||
import "package:flutter_hooks/flutter_hooks.dart";
|
||||
import "package:hooks_riverpod/hooks_riverpod.dart";
|
||||
import "package:media_kit/media_kit.dart";
|
||||
import "package:nexus/controllers/client.dart";
|
||||
import "package:nexus/helpers/extensions/save_attachment.dart";
|
||||
import "package:nexus/models/info/audio.dart";
|
||||
|
|
@ -18,9 +18,7 @@ class const AudioPlayer(
|
|||
}) extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final player = useMemoized(
|
||||
() => Player(configuration: .new(bufferSize: 128 * 1024 * 1024)),
|
||||
);
|
||||
final player = useMemoized(audioplayers.AudioPlayer.new);
|
||||
final loaded = useState(false);
|
||||
|
||||
useEffect(() {
|
||||
|
|
@ -29,19 +27,39 @@ class const AudioPlayer(
|
|||
.read(ClientController.provider.notifier)
|
||||
.downloadMedia(.new(mxc: uri, encrypted: encrypted));
|
||||
if (!context.mounted) return;
|
||||
await player.open(Media(audio.path), play: false);
|
||||
// Keeps the audio loaded after it finishes, so it can be replayed
|
||||
await player.setReleaseMode(.stop);
|
||||
await player.setSource(audioplayers.DeviceFileSource(audio.path));
|
||||
if (context.mounted) loaded.value = true;
|
||||
});
|
||||
|
||||
return player.dispose;
|
||||
}, []);
|
||||
|
||||
final state = useStream(
|
||||
player.onPlayerStateChanged,
|
||||
initialData: player.state,
|
||||
).requireData;
|
||||
final position = useStream(
|
||||
player.onPositionChanged,
|
||||
initialData: Duration.zero,
|
||||
).requireData;
|
||||
final duration = useStream(
|
||||
player.onDurationChanged,
|
||||
initialData: Duration.zero,
|
||||
).requireData;
|
||||
final playing = state == .playing;
|
||||
|
||||
return Card(
|
||||
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||
child: Padding(
|
||||
padding: .symmetric(horizontal: 8),
|
||||
child: PlayerControls(
|
||||
player,
|
||||
playing: playing,
|
||||
position: position,
|
||||
duration: duration,
|
||||
onPlayPause: playing ? player.pause : player.resume,
|
||||
onSeek: player.seek,
|
||||
loading: !loaded.value,
|
||||
size: info?.size,
|
||||
actions: .new([
|
||||
|
|
|
|||
|
|
@ -1,39 +1,25 @@
|
|||
import "dart:math";
|
||||
|
||||
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
||||
import "package:flutter_hooks/flutter_hooks.dart";
|
||||
import "package:material_ui/material_ui.dart";
|
||||
import "package:media_kit/media_kit.dart";
|
||||
import "package:nexus/helpers/extensions/size_to_string.dart";
|
||||
|
||||
/// Play/pause, position and seeking controls for a media_kit [Player].
|
||||
class const PlayerControls(
|
||||
final Player player, {
|
||||
/// Play/pause, position and seeking controls, for any player.
|
||||
class const PlayerControls({
|
||||
required final bool playing,
|
||||
required final Duration position,
|
||||
required final Duration duration,
|
||||
required final VoidCallback onPlayPause,
|
||||
required final ValueChanged<Duration> onSeek,
|
||||
final bool loading = false,
|
||||
final bool buffering = false,
|
||||
final Color? color,
|
||||
final int? size,
|
||||
final IList<Widget> actions = const .empty(),
|
||||
super.key,
|
||||
}) extends HookWidget {
|
||||
}) extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final playing = useStream(
|
||||
player.stream.playing,
|
||||
initialData: player.state.playing,
|
||||
).requireData;
|
||||
final buffering = useStream(
|
||||
player.stream.buffering,
|
||||
initialData: player.state.buffering,
|
||||
).requireData;
|
||||
final position = useStream(
|
||||
player.stream.position,
|
||||
initialData: player.state.position,
|
||||
).requireData;
|
||||
final duration = useStream(
|
||||
player.stream.duration,
|
||||
initialData: player.state.duration,
|
||||
).requireData;
|
||||
|
||||
String format(Duration duration) {
|
||||
final minutes = duration.inMinutes
|
||||
.remainder(60)
|
||||
|
|
@ -61,7 +47,7 @@ class const PlayerControls(
|
|||
child: CircularProgressIndicator(padding: .all(12), color: color),
|
||||
)
|
||||
: IconButton(
|
||||
onPressed: player.playOrPause,
|
||||
onPressed: onPlayPause,
|
||||
color: color,
|
||||
tooltip: playing ? "Pause" : "Play",
|
||||
icon: Icon(playing ? Icons.pause_circle : Icons.play_circle),
|
||||
|
|
@ -73,7 +59,7 @@ class const PlayerControls(
|
|||
value: min(position.inMilliseconds.toDouble(), max),
|
||||
onChanged: loading
|
||||
? null
|
||||
: (value) => player.seek(.new(milliseconds: value.toInt())),
|
||||
: (value) => onSeek(.new(milliseconds: value.toInt())),
|
||||
);
|
||||
|
||||
return LayoutBuilder(
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
import "dart:async";
|
||||
|
||||
import "package:better_player/better_player.dart";
|
||||
import "package:material_ui/material_ui.dart";
|
||||
import "package:hooks_riverpod/hooks_riverpod.dart";
|
||||
import "package:nexus/controllers/client.dart";
|
||||
import "package:nexus/helpers/extensions/save_attachment.dart";
|
||||
import "package:nexus/models/info/video.dart";
|
||||
import "package:flutter_hooks/flutter_hooks.dart";
|
||||
import "package:media_kit/media_kit.dart";
|
||||
import "package:media_kit_video/media_kit_video.dart";
|
||||
import "package:nexus/widgets/players/player_controls.dart";
|
||||
|
||||
class const VideoPlayer(
|
||||
|
|
@ -19,38 +18,45 @@ class const VideoPlayer(
|
|||
}) extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final player = useMemoized(
|
||||
() => Player(configuration: .new(bufferSize: 128 * 1024 * 1024)),
|
||||
);
|
||||
final controller = useMemoized(() => VideoController(player));
|
||||
final aspectRatio = switch (info) {
|
||||
VideoInfo(:final width?, :final height?) when width > 0 && height > 0 =>
|
||||
width / height,
|
||||
_ => 16 / 9,
|
||||
};
|
||||
|
||||
final loaded = useState(false);
|
||||
|
||||
final controller = useMemoized(
|
||||
() => BetterPlayerController(
|
||||
PlayerConfiguration(
|
||||
aspectRatio: aspectRatio,
|
||||
fit: .contain,
|
||||
controlsConfiguration: PlayerControlsConfiguration(
|
||||
playerTheme: .custom,
|
||||
customControlsBuilder: (controller, _) => HookBuilder(
|
||||
builder: (context) {
|
||||
final isLoaded = useValueListenable(loaded);
|
||||
final value = useState(controller.videoPlayerValue);
|
||||
useEffect(() {
|
||||
scheduleMicrotask(() async {
|
||||
final video = await ref
|
||||
.read(ClientController.provider.notifier)
|
||||
.downloadMedia(.new(mxc: uri, encrypted: encrypted));
|
||||
if (!context.mounted) return;
|
||||
await player.open(Media(video.path), play: false);
|
||||
if (context.mounted) loaded.value = true;
|
||||
});
|
||||
void listener() => value.value = controller.videoPlayerValue;
|
||||
controller.addVideoListener(listener);
|
||||
return () => controller.removeVideoListener(listener);
|
||||
}, [controller]);
|
||||
|
||||
return player.dispose;
|
||||
}, []);
|
||||
final playing = value.value?.isPlaying ?? false;
|
||||
|
||||
final controls = useCallback(
|
||||
(VideoState _) =>
|
||||
// Until media_kit moves to material_ui, this Material is needed.
|
||||
Material(
|
||||
// better_player doesn't use material_ui, so this Material is needed.
|
||||
return Material(
|
||||
type: .transparency,
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: loaded,
|
||||
builder: (_, loaded, _) => Stack(
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: GestureDetector(
|
||||
behavior: .opaque,
|
||||
onTap: loaded ? player.playOrPause : null,
|
||||
onTap: isLoaded
|
||||
? playing
|
||||
? controller.pause
|
||||
: controller.play
|
||||
: null,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
|
|
@ -86,28 +92,29 @@ class const VideoPlayer(
|
|||
child: Padding(
|
||||
padding: const .only(left: 4, right: 4, top: 16),
|
||||
child: PlayerControls(
|
||||
player,
|
||||
loading: !loaded,
|
||||
playing: playing,
|
||||
buffering: value.value?.isBuffering ?? false,
|
||||
position: value.value?.position ?? .zero,
|
||||
duration: value.value?.duration ?? .zero,
|
||||
onPlayPause: playing
|
||||
? controller.pause
|
||||
: controller.play,
|
||||
onSeek: controller.seekTo,
|
||||
loading: !isLoaded,
|
||||
size: info?.size,
|
||||
color: Colors.white,
|
||||
actions: .new([
|
||||
Builder(
|
||||
builder: (context) {
|
||||
final fullscreen = isFullscreen(context);
|
||||
|
||||
return IconButton(
|
||||
onPressed: () => toggleFullscreen(context),
|
||||
IconButton(
|
||||
onPressed: controller.toggleFullScreen,
|
||||
color: Colors.white,
|
||||
tooltip: fullscreen
|
||||
tooltip: controller.isFullScreen
|
||||
? "Exit fullscreen"
|
||||
: "Fullscreen",
|
||||
icon: Icon(
|
||||
fullscreen
|
||||
controller.isFullScreen
|
||||
? Icons.fullscreen_exit
|
||||
: Icons.fullscreen,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
]),
|
||||
),
|
||||
|
|
@ -116,16 +123,26 @@ class const VideoPlayer(
|
|||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
[uri, encrypted, filename, info],
|
||||
);
|
||||
|
||||
final aspectRatio = switch (info) {
|
||||
VideoInfo(:final width?, :final height?) when width > 0 && height > 0 =>
|
||||
width / height,
|
||||
_ => 16 / 9,
|
||||
};
|
||||
useEffect(() {
|
||||
scheduleMicrotask(() async {
|
||||
final video = await ref
|
||||
.read(ClientController.provider.notifier)
|
||||
.downloadMedia(.new(mxc: uri, encrypted: encrypted));
|
||||
if (!context.mounted) return;
|
||||
await controller.setupDataSource(.file(video.path));
|
||||
if (context.mounted) loaded.value = true;
|
||||
});
|
||||
|
||||
return null;
|
||||
}, []);
|
||||
|
||||
return ConstrainedBox(
|
||||
constraints: const .new(maxHeight: 300),
|
||||
|
|
@ -133,7 +150,7 @@ class const VideoPlayer(
|
|||
aspectRatio: aspectRatio,
|
||||
child: ClipRRect(
|
||||
borderRadius: .circular(12),
|
||||
child: Video(controller: controller, controls: controls),
|
||||
child: BetterPlayer(controller: controller),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@
|
|||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <app_links_linux/app_links_plugin_linux.h>
|
||||
#include <audioplayers_linux/audioplayers_linux_plugin.h>
|
||||
#include <better_player_linux/better_player_linux_plugin.h>
|
||||
#include <dynamic_color/dynamic_color_plugin.h>
|
||||
#include <file_selector_linux/file_selector_plugin.h>
|
||||
#include <location/location_plugin.h>
|
||||
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
|
||||
#include <media_kit_video/media_kit_video_plugin.h>
|
||||
#include <pasteboard/pasteboard_plugin.h>
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
|
||||
|
|
@ -19,6 +19,12 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
|||
g_autoptr(FlPluginRegistrar) app_links_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "AppLinksPluginLinux");
|
||||
app_links_plugin_linux_register_with_registrar(app_links_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin");
|
||||
audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) better_player_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "BetterPlayerLinuxPlugin");
|
||||
better_player_linux_plugin_register_with_registrar(better_player_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) dynamic_color_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin");
|
||||
dynamic_color_plugin_register_with_registrar(dynamic_color_registrar);
|
||||
|
|
@ -28,12 +34,6 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
|||
g_autoptr(FlPluginRegistrar) location_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "LocationPlugin");
|
||||
location_plugin_register_with_registrar(location_registrar);
|
||||
g_autoptr(FlPluginRegistrar) media_kit_libs_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitLibsLinuxPlugin");
|
||||
media_kit_libs_linux_plugin_register_with_registrar(media_kit_libs_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) media_kit_video_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitVideoPlugin");
|
||||
media_kit_video_plugin_register_with_registrar(media_kit_video_registrar);
|
||||
g_autoptr(FlPluginRegistrar) pasteboard_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "PasteboardPlugin");
|
||||
pasteboard_plugin_register_with_registrar(pasteboard_registrar);
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@
|
|||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
app_links_linux
|
||||
audioplayers_linux
|
||||
better_player_linux
|
||||
dynamic_color
|
||||
file_selector_linux
|
||||
location
|
||||
media_kit_libs_linux
|
||||
media_kit_video
|
||||
pasteboard
|
||||
url_launcher_linux
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,12 +7,14 @@
|
|||
stdenv.cc
|
||||
go
|
||||
git
|
||||
ffmpeg-headless
|
||||
|
||||
libGL
|
||||
(flutter.override {
|
||||
# audioplayers plays audio through GStreamer
|
||||
extraPkgConfigPackages = [
|
||||
mpv-unwrapped
|
||||
libass
|
||||
gst_all_1.gstreamer
|
||||
gst_all_1.gst-plugins-base
|
||||
];
|
||||
})
|
||||
]
|
||||
|
|
@ -25,6 +27,27 @@
|
|||
];
|
||||
|
||||
env = lib.optionalAttrs pkgs.stdenv.isLinux {
|
||||
LD_LIBRARY_PATH = "./build/native_assets/linux:${lib.makeLibraryPath [ pkgs.zlib ]}";
|
||||
# better_player loads libmpv at runtime to play videos
|
||||
LD_LIBRARY_PATH = "./build/native_assets/linux:${
|
||||
lib.makeLibraryPath [
|
||||
pkgs.zlib
|
||||
pkgs.mpv-unwrapped
|
||||
]
|
||||
}";
|
||||
# audioplayers links GStreamer by name only, without its library directory
|
||||
LIBRARY_PATH = lib.makeLibraryPath [
|
||||
pkgs.gst_all_1.gstreamer
|
||||
pkgs.gst_all_1.gst-plugins-base
|
||||
pkgs.glib
|
||||
];
|
||||
GST_PLUGIN_SYSTEM_PATH_1_0 = lib.makeSearchPathOutput "lib" "lib/gstreamer-1.0" (
|
||||
with pkgs.gst_all_1;
|
||||
[
|
||||
gstreamer
|
||||
gst-plugins-base
|
||||
gst-plugins-good
|
||||
gst-libav
|
||||
]
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
lib,
|
||||
callPackage,
|
||||
mpv-unwrapped,
|
||||
libass,
|
||||
gst_all_1,
|
||||
ffmpeg-headless,
|
||||
libxext,
|
||||
libxfixes,
|
||||
libclang,
|
||||
|
|
@ -39,8 +40,9 @@ flutter.buildFlutterApplication {
|
|||
nativeBuildInputs = [ (callPackage ./hook_pkg_config.nix { }) ];
|
||||
|
||||
buildInputs = [
|
||||
mpv-unwrapped
|
||||
libass
|
||||
# audioplayers plays audio through GStreamer
|
||||
gst_all_1.gstreamer
|
||||
gst_all_1.gst-plugins-base
|
||||
# nativeapi includes XInput2.h, which needs these, but xi.pc only lists them privately
|
||||
libxext
|
||||
libxfixes
|
||||
|
|
@ -54,6 +56,7 @@ flutter.buildFlutterApplication {
|
|||
|
||||
gitHashes = {
|
||||
linkify = "sha256-TpMD6+0zyY6i9l+6d8ErnVufmepCv362rCtnbOht/z4=";
|
||||
location = "sha256-zWnffXiK1LD4Ln23coPozBjYfTlhZmBhC5Z8mCdAgwQ=";
|
||||
fab_m3e = "sha256-5V9m6yY0jimx2gh7lQHYg4HDKQ4Wrl0ATmBhw5DkQMI=";
|
||||
fluttertagger = "sha256-tHUNU2+fBPkq5UK5YRi3SWs1zF2PIPz6RgSbwignU/I=";
|
||||
m3e_design = "sha256-5V9m6yY0jimx2gh7lQHYg4HDKQ4Wrl0ATmBhw5DkQMI=";
|
||||
|
|
@ -69,8 +72,24 @@ flutter.buildFlutterApplication {
|
|||
install -D assets/bundled/icon.svg $out/share/icons/hicolor/scalable/apps/nexus.svg
|
||||
install -Dm755 linux/*.desktop -t $out/share/applications
|
||||
install -Dm644 linux/*.service -t $out/share/dbus-1/services
|
||||
# better_player loads libmpv at runtime to play videos, and audioplayers
|
||||
# needs GStreamer's plugins to decode audio
|
||||
# gomuks uses ffmpeg and ffprobe for video thumbnails and metadata
|
||||
wrapProgram $out/bin/nexus \
|
||||
--suffix LD_LIBRARY_PATH : $out/app/nexus/lib
|
||||
--suffix LD_LIBRARY_PATH : $out/app/nexus/lib \
|
||||
--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ mpv-unwrapped ]} \
|
||||
--prefix PATH : ${lib.makeBinPath [ ffmpeg-headless ]} \
|
||||
--prefix GST_PLUGIN_SYSTEM_PATH_1_0 : ${
|
||||
lib.makeSearchPathOutput "lib" "lib/gstreamer-1.0" (
|
||||
with gst_all_1;
|
||||
[
|
||||
gstreamer
|
||||
gst-plugins-base
|
||||
gst-plugins-good
|
||||
gst-libav
|
||||
]
|
||||
)
|
||||
}
|
||||
'';
|
||||
|
||||
meta = {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "my_application.h"
|
||||
|
||||
#include <clocale>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <flutter_linux/flutter_linux.h>
|
||||
|
|
@ -301,6 +302,9 @@ static void my_application_startup(
|
|||
G_APPLICATION_CLASS(
|
||||
my_application_parent_class)
|
||||
->startup(application);
|
||||
|
||||
// mpv hates normal locales
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
}
|
||||
|
||||
static void my_application_shutdown(
|
||||
|
|
|
|||
|
|
@ -1,2 +1 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||
|
|
|
|||
|
|
@ -1,2 +1 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ import FlutterMacOS
|
|||
import Foundation
|
||||
|
||||
import app_links
|
||||
import audioplayers_darwin
|
||||
import better_player_macos
|
||||
import dynamic_color
|
||||
import file_selector_macos
|
||||
import flutter_local_notifications
|
||||
import location
|
||||
import media_kit_libs_macos_video
|
||||
import media_kit_video
|
||||
import package_info_plus
|
||||
import pasteboard
|
||||
import shared_preferences_foundation
|
||||
|
|
@ -20,12 +20,12 @@ import wakelock_plus
|
|||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
|
||||
AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
|
||||
BetterPlayerPlugin.register(with: registry.registrar(forPlugin: "BetterPlayerPlugin"))
|
||||
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
|
||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
|
||||
LocationPlugin.register(with: registry.registrar(forPlugin: "LocationPlugin"))
|
||||
MediaKitLibsMacosVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitLibsMacosVideoPlugin"))
|
||||
MediaKitVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitVideoPlugin"))
|
||||
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
||||
PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue