Files
ux/lib/builder.dart
agra 2531fdcb74 FFmpeg software H.264 decoder: opt-in via pubspec flag
- Gate buildFfmpegJni + jniLibs packaging on `ux: enable_ffmpeg` in the
  consuming app's pubspec (default off) -- no LGPL / H.264-patent
  exposure unless explicitly enabled
- appInfoBuilder generates kUxEnableFfmpeg from the same flag so apps
  register the FFmpeg LGPL notice eagerly, pubspec-only (no dart-define)
- Add registerFfmpegLicense() + bundled LGPL-2.1 text asset
- FFmpeg compliance docs (LICENSES-3RDPARTY.md, android/ffmpeg/README.md)
- Network video streaming: XVideoPlayerController.network
2026-06-15 20:30:07 +03:00

66 lines
2.3 KiB
Dart

import 'dart:async';
import 'package:build/build.dart';
Builder appInfoBuilder(BuilderOptions options) => _AppInfoBuilder();
class _AppInfoBuilder implements Builder {
@override
Map<String, List<String>> get buildExtensions => const {
r'$package$': ['lib/app_info.g.dart'],
};
@override
Future<void> build(BuildStep buildStep) async {
final pkg = buildStep.inputId.package;
final raw = await buildStep.readAsString(AssetId(pkg, 'pubspec.yaml'));
final match =
RegExp(r'^version:\s*([^\s#]+)', multiLine: true).firstMatch(raw);
final combined = match?.group(1) ?? '0.0.0+0';
final plus = combined.indexOf('+');
final version = plus < 0 ? combined : combined.substring(0, plus);
final buildNumber =
plus < 0 ? 0 : int.tryParse(combined.substring(plus + 1)) ?? 0;
final enableFfmpeg = _readUxFlag(raw, 'enable_ffmpeg');
await buildStep.writeAsString(
AssetId(pkg, 'lib/app_info.g.dart'),
'''
// GENERATED by build_runner from pubspec.yaml — do not edit.
import 'package:ux/ux.dart';
const kAppInfo = AppInfo(version: '$version', buildNumber: $buildNumber);
/// Mirrors the app's `ux: enable_ffmpeg` pubspec setting as a compile-time
/// constant. Gate FFmpeg-dependent code (e.g. registerFfmpegLicense()) on
/// this — pubspec stays the single source of truth.
const kUxEnableFfmpeg = $enableFfmpeg;
''',
);
}
/// Reads a boolean under the top-level `ux:` mapping, e.g. `ux: { $key: ... }`.
/// Scans manually (no YAML dep) and ignores the indented `ux:` dependency
/// entry by only entering the block on a non-indented `ux:` line.
static bool _readUxFlag(String pubspec, String key) {
var inUxBlock = false;
var enabled = false;
for (final rawLine in pubspec.split('\n')) {
final hash = rawLine.indexOf('#');
final line = hash >= 0 ? rawLine.substring(0, hash) : rawLine;
if (line.trim().isEmpty) continue;
final indented = line.startsWith(' ') || line.startsWith('\t');
if (!indented) {
inUxBlock = line.trimRight() == 'ux:' || line.startsWith('ux:');
} else if (inUxBlock) {
final t = line.trim();
if (t.startsWith('$key:')) {
enabled = t.substring(key.length + 1).trim().toLowerCase() == 'true';
}
}
}
return enabled;
}
}