anonymhk / betterplayer Goto Github PK
View Code? Open in Web Editor NEWBug fix version for betterplayer
License: Apache License 2.0
Bug fix version for betterplayer
License: Apache License 2.0
History check
yes, I've checked the issue history and I didn't find anything which may solve my issue.
Describe the bug
black strip on the left side of the video in fullscreen mode on Android Devices only.
To Reproduce
Go to fullscreen mode on any android device
*Example code
import 'package:better_player/better_player.dart';
import 'package:flutter/material.dart';
class VideoScreen extends StatefulWidget {
const VideoScreen({super.key});
@OverRide
State createState() => _VideoScreenState();
}
class _VideoScreenState extends State {
late BetterPlayerController _betterPlayerController;
bool loading = true;
@OverRide
void initState() {
super.initState();
initializePlayer();
}
initializePlayer() {
BetterPlayerConfiguration betterPlayerConfiguration =
BetterPlayerConfiguration(
// aspectRatio: 16 / 9,
// fit: BoxFit.contain,
controlsConfiguration: BetterPlayerControlsConfiguration(
playIcon: Icons.play_arrow_rounded,
enablePlayPause: false,
pauseIcon: Icons.pause_rounded,
enableFullscreen: true,
iconsColor: Colors.white,
progressBarBackgroundColor: Colors.white.withOpacity(0.5),
progressBarBufferedColor: Colors.white,
progressBarHandleColor: Colors.red,
progressBarPlayedColor: Colors.red,
overflowMenuIconsColor: Colors.white,
overflowModalColor: Colors.black54,
overflowModalTextColor: Colors.white
),
autoPlay: true,
fullScreenByDefault: false,
allowedScreenSleep: false,
);
BetterPlayerDataSource dataSource = BetterPlayerDataSource(
BetterPlayerDataSourceType.network,
"https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8",
useAsmsSubtitles: true,
videoFormat: BetterPlayerVideoFormat.hls,
);
_betterPlayerController = BetterPlayerController(betterPlayerConfiguration);
_betterPlayerController.setupDataSource(dataSource);
loading = false;
// SystemChrome.setPreferredOrientations([
// DeviceOrientation.landscapeLeft,
// ]);
// SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
// _betterPlayerController.addEventsListener((event){
// if(event.betterPlayerEventType == BetterPlayerEventType.play || event.betterPlayerEventType == BetterPlayerEventType.pause) {
// Vibrate.feedback(FeedbackType.medium);
// }
// });
setState(() {});
}
@OverRide
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: loading ? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: const [
CircularProgressIndicator(
color: Colors.white,
),
SizedBox(height: 20),
Text(
'Loading...',
style: TextStyle(color: Colors.white),
),
],
),
) : BetterPlayer(controller: _betterPlayerController),
);;
}
}
download the package from master branch of better_player package and change the code and kotlin version as explained in this github issue -- jhomlala/betterplayer#1113
Expected behavior
There should not be any black strip on the left side of the screen when going to fullscreen mode
Flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.7.5, on macOS 13.2.1 22D68 darwin-x64, locale en-GB)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 14.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.3)
[✓] VS Code (version 1.80.1)
[✓] Connected device (3 available)
[✓] HTTP Host Availability
• No issues found!
Better Player version
Smartphone (please complete the following information):
There is issue with local m3u8 on play time, it is not detecting subtitle and audio while playing hls content from local storage in android.
History check
I confirm that i couldn't find a similar problem in the issue history.
Describe the bug
Opening the video player crashed the app. The bug happened only once, on a real device. I couldn't reproduce the bug anymore. I only have the Firebase Crashalytics log at the time of the crash:
Crashed: com.apple.NSURLSession-delegate
0 libswiftCore.dylib 0x3dcd08 swift_isUniquelyReferenced_nonNull_native + 38
1 better_player 0x15b60 $sSlsE3mapySayqd__Gqd__7ElementQzKXEKlFShySo29AVAssetResourceLoadingRequestCG_AFSgTg5039$s13better_player17CachingPlayerItemC22d46LoaderDelegateC22processPendingRequestsyyFSo07c3F14eF11CSgAHXEfU0_13better_player0ijK0C0dmN0CTf1cn_nTf4ng_n + 444
2 better_player 0x16034 $s13better_player17CachingPlayerItemC22ResourceLoaderDelegateC10urlSession_8dataTask10didReceiveySo12NSURLSessionC_So0o4DataL0C10Foundation0P0VtFTf4dnnn_n + 232
3 better_player 0x11958 $s13better_player17CachingPlayerItemC22ResourceLoaderDelegateC10urlSession_8dataTask10didReceiveySo12NSURLSessionC_So0o4DataL0C10Foundation0P0VtFTo + 120
4 FirebasePerformance 0x174bc __InstrumentURLSessionDataTaskDidReceiveData_block_invoke + 160
5 CFNetwork 0x87c74 _CFHostIsDomainTopLevelForCertificatePolicy + 20824
6 libdispatch.dylib 0x1e6c _dispatch_call_block_and_release + 32
7 libdispatch.dylib 0x3a30 _dispatch_client_callout + 20
8 libdispatch.dylib 0xb124 _dispatch_lane_serial_drain + 668
9 libdispatch.dylib 0xbcb4 _dispatch_lane_invoke + 444
10 libdispatch.dylib 0x16500 _dispatch_workloop_worker_thread + 648
11 libsystem_pthread.dylib 0x10bc _pthread_wqthread + 288
12 libsystem_pthread.dylib 0xe5c start_wqthread + 8
To Reproduce
*Example code
void _initVideoPlayer(String url) {
BetterPlayerDataSource betterPlayerDataSource = BetterPlayerDataSource(
BetterPlayerDataSourceType.network,
url,
cacheConfiguration: BetterPlayerCacheConfiguration(
useCache: true,
maxCacheFileSize: 250 * 1024 * 1024,
maxCacheSize: 4 * 1000 * 1024 * 1024,
key: widget.firebaseVideoResourceURL,
),
);
_betterPlayerController = BetterPlayerController(
BetterPlayerConfiguration(
aspectRatio: 16 / 9,
expandToFill: false,
fullScreenAspectRatio: 16 / 9,
fit: BoxFit.fitHeight,
eventListener: (event) {
setState(() {
if (event.betterPlayerEventType ==
BetterPlayerEventType.openFullscreen) {
_betterPlayerController?.setControlsEnabled(true);
if (widget.controllerEventEmitter != null) {
widget.controllerEventEmitter?.isFullscreen = true;
}
}
if (event.betterPlayerEventType ==
BetterPlayerEventType.hideFullscreen) {
_betterPlayerController?.setControlsEnabled(false);
if (widget.controllerEventEmitter != null) {
widget.controllerEventEmitter?.isFullscreen = false;
}
}
if (event.betterPlayerEventType == BetterPlayerEventType.pause) {
_playPauseBtn = Icon(
Platform.isIOS
? CupertinoIcons.play_arrow_solid
: Icons.play_arrow_outlined,
color: AppColors.accentColor,
size: 28,
);
}
if (event.betterPlayerEventType == BetterPlayerEventType.play) {
_playPauseBtn = Icon(
Platform.isIOS
? CupertinoIcons.pause_solid
: Icons.pause_outlined,
color: AppColors.accentColor,
size: 28,
);
}
});
},
autoPlay: widget.autoplay,
looping: true,
// autoDetectFullscreenAspectRatio: true,
deviceOrientationsAfterFullScreen: [
DeviceOrientation.portraitUp,
],
controlsConfiguration: const BetterPlayerControlsConfiguration(
showControlsOnInitialize: false,
controlBarColor: Colors.transparent,
loadingColor: AppColors.accentColor,
backgroundColor: Colors.transparent,
progressBarPlayedColor: AppColors.accentColor,
enableQualities: false,
enableSubtitles: false,
enableAudioTracks: false,
),
showPlaceholderUntilPlay: widget.placeholder != null,
placeholder: widget.placeholder
),
betterPlayerDataSource: betterPlayerDataSource,
);
_betterPlayerController?.setControlsEnabled(false);
}
Expected behavior
The video player should not crash
Screenshots
If applicable, add screenshots to help explain your problem.
Flutter doctor
[✓] Flutter (Channel stable, 3.10.1, on macOS 13.1 22C65 darwin-arm64, locale en-RO)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.1)
[✓] VS Code (version 1.77.3)
[✓] Connected device (4 available)
[✓] Network resources
• No issues found!
Better Player version
Smartphone (please complete the following information):
Additional context
Add any other context about the problem here.
History check
Yes - I've searched all the issues. Fount the single one (no answers at all) in the original, abandoned repository.
Describe the bug
If you change the quality while streaming on iOS, nothing happens, unless you manually seek to another point in the video.
This works fine on Android.
To Reproduce
Steps to reproduce the behavior:
Play a video
Invoke the Quality pop-up
Change to lower quality
Observe nothing changes
Manually seek using the slider bar - see the quality change
Expected behavior
Quality should change after being selected (as it does on Android correctly)
Workarounds I've tried
Listen to changedTrack event
pause video, seekTo time + 1/-1, play
doesn't work as per manual seeking.
Flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.10.5, on macOS 13.4 22F66 darwin-arm64, locale en-PL)
[✓] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1)
[✓] Xcode - develop for iOS and macOS (Xcode 14.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.1)
[✓] IntelliJ IDEA Community Edition (version 2021.3.3)
[✓] VS Code (version 1.77.3)
[✓] Connected device (4 available)
[✓] Network resources
Better Player version
Version: 0.0.83
Smartphone (please complete the following information):
Device: iPhone12
OS: 16
Describe the bug
Un able to play the video on android and ios
To Reproduce
Steps to reproduce the behavior:
initilise player with below streaming link
use this link
Expected behavior
if Bandwidth is null it should steam adaptivily
Better Player version
Smartphone :
Additional context
E/ExoPlayerImplInternal(14577): Caused by: com.google.android.exoplayer2.ParserException: Couldn't match [^-]BANDWIDTH=(\d+)\b in #EXT-X-STREAM-INF:BANDWIDTH=None,RESOLUTION=426x240
MY m3u8 link curl result
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=None,RESOLUTION=426x240
240p/video.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=None,RESOLUTION=640x360
360p/video.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=None,RESOLUTION=854x480
480p/video.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=None,RESOLUTION=1280x720
720p/video.m3u8
Need to move androidx.media3
https://github.com/androidx/media/releases/tag/1.1.0
Migration Guide
https://developer.android.com/guide/topics/media/media3/getting-started/migration-guide
BetterPlayerNotificationConfiguration(
showNotification: true,
title: room.title,
author: room.nick,
activityName: "MainActivity",
)
when add option imageUrl: room.avatar,
,I got this err.
E/BetterPlayerPlugin( 3331): SetupNotification failed
E/BetterPlayerPlugin( 3331): java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Void
E/BetterPlayerPlugin( 3331): at com.jhomlala.better_player.BetterPlayerPlugin.setupNotification(BetterPlayerPlugin.kt:371)
E/BetterPlayerPlugin( 3331): at com.jhomlala.better_player.BetterPlayerPlugin.onMethodCall(BetterPlayerPlugin.kt:162)
E/BetterPlayerPlugin( 3331): at com.jhomlala.better_player.BetterPlayerPlugin.onMethodCall(BetterPlayerPlugin.kt:138)
E/BetterPlayerPlugin( 3331): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:258)
E/BetterPlayerPlugin( 3331): at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295)
E/BetterPlayerPlugin( 3331): at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:322)
E/BetterPlayerPlugin( 3331): at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
E/BetterPlayerPlugin( 3331): at android.os.Handler.handleCallback(Handler.java:873)
E/BetterPlayerPlugin( 3331): at android.os.Handler.dispatchMessage(Handler.java:99)
E/BetterPlayerPlugin( 3331): at android.os.Looper.loop(Looper.java:193)
E/BetterPlayerPlugin( 3331): at android.app.ActivityThread.main(ActivityThread.java:6825)
E/BetterPlayerPlugin( 3331): at java.lang.reflect.Method.invoke(Native Method)
E/BetterPlayerPlugin( 3331): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
E/BetterPlayerPlugin( 3331): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:860)
History check
Checked
Describe the bug
On the example app on Android, the Widevine Video under "DRM" shows the "Video can't be played" error.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Video should play
Flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.10.2, on macOS 13.4 22F66 darwin-arm64, locale es-ES)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.2)
[✓] VS Code (version 1.79.0)
[✓] Connected device (4 available)
[✓] Network resources
• No issues found!
Better Player version
Smartphone (please complete the following information):
wakelock stooped being maintained.
fluttercommunity decided to take it and published wakelock_plus.
Let's move to it.
History check
yes, I've checked the issue history and I didn't find anything which may solve my issue..
Describe the bug
When i play or load video from url network, video dont play anymore.
To Reproduce
Steps to reproduce the behavior:
*Example code
You can view full coe in here
Expected behavior
A clear and concise description of what you expected to happen.
Flutter doctor
[✓] Flutter (Channel stable, 3.13.4, on macOS 14.0 23A339 darwin-arm64, locale en-ID)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.0)
[✗] Chrome - develop for the web (Cannot find Chrome executable at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome)
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[✓] Android Studio (version 2022.3)
[✓] VS Code (version 1.82.2)
[✓] Connected device (3 available)
! Error: Browsing on the local area network for Andri's iPhone . Ensure the device is unlocked and attached with a cable or associated with the same local
area network as this Mac.
The device must be opted into Developer Mode to connect wirelessly. (code -27)
[✓] Network resources
! Doctor found issues in 1 category.
Better Player version
Smartphone (please complete the following information):
There are 2 good pr that I would like to see added
Describe the bug
Hello There,
I am using the better player in one of our latest application and there I am working on Rotation feature of video when click on button or when the device orientation changed.
So here, the rotation feature is working fine in iOS version 15 and less. But for the iOS version 16.0 or more, it's conflicting.
Can anyone help me here please?
To Reproduce
Steps to reproduce the behavior:
Better Player version
Smartphone:
Describe the bug
The value BetterPlayerEventType.finished
arrives twice in the callback addEventsListener
when video is completed using skeepTo
function
To Reproduce
Steps to reproduce the behavior:
controller.addEventsListener(myFunction);
for the videovoid myFunction(BetterPlayerEvent event) {
if (event.betterPlayerEventType == BetterPlayerEventType.finished) {
print('Video finished');
}
}
controller.seekTo(videoPosition + Duration(seconds: 10));
*Example code
Paste here your minimal reproducible code. This code should be ready to copy-paste-run.
Expected behavior
addEventsListener
should call the event function only once with BetterPlayerEventType.finished
Screenshots
If applicable, add screenshots to help explain your problem.
Flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.10.2, on Ubuntu 23.04 6.3.6-060306-generic, locale en_IL)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Chrome - develop for the web
[✓] Linux toolchain - develop for Linux desktop
[✓] Android Studio (version 2022.2)
[✓] Android Studio (version 2021.3)
[✓] VS Code
[✓] Connected device (3 available)
[✓] Network resources
• No issues found!
Better Player version
0.0.83
from the main packageSmartphone (please complete the following information):
Android emulator
Additional context
Add any other context about the problem here.
Describe the bug
Iphone 8 and lower models might have tighter maximum memory allocation sizes constrained by the OS. If we use useCaching = true on an iPhone 8 and try to play video over 100mb, the app crashes with 'NSMallocException', reason: 'Failed to grow buffer' in the haveEnoughDataToFulfillRequest function from the CachingPlayerItem class of the BetterPlayer ios library.
The cause seems to be that songDataUnwrapped byte buffer is allocated with the entire video memory and when dataToRespond = songDataUnwrapped.subdata(in: Range(uncheckedBounds: (currentOffset, currentOffset + bytesToRespond))) call happens, another byte array is allocated in the dataToRespond variable, exceeding the app memory allocation limits (wich i couldn't find anywhere in the Apple documentation, the NSMallocException is even marked as 'Obsolete' by them https://developer.apple.com/documentation/foundation/nsmallocexception.
The current workaround is to disable videoPlayer caching for devices older than Iphone X.
I don't have any Swift or IOS APIs experience and my time is limited these weeks, if there is a fix possible and you don't have an older iPhone available i can be offered guidance so i can try to fix and test it.
func haveEnoughDataToFulfillRequest(_ dataRequest: AVAssetResourceLoadingDataRequest) -> Bool {
let requestedOffset = Int(dataRequest.requestedOffset)
let requestedLength = dataRequest.requestedLength
let currentOffset = Int(dataRequest.currentOffset)
guard let songDataUnwrapped = mediaData,
songDataUnwrapped.count > currentOffset else {
// Don't have any data at all for this request.
return false
}
let bytesToRespond = min(songDataUnwrapped.count - currentOffset, requestedLength)
//here is the crash happening
let dataToRespond = songDataUnwrapped.subdata(in: Range(uncheckedBounds: (currentOffset, currentOffset + bytesToRespond)))
dataRequest.respond(with: dataToRespond)
return songDataUnwrapped.count >= requestedLength + requestedOffset
}
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The app should not crash and the cache should work.
Flutter doctor
[✓] Flutter (Channel stable, 3.10.1, on macOS 13.1 22C65 darwin-arm64, locale en-RO)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.1)
[✓] VS Code (version 1.77.3)
[✓] Connected device (4 available)
[✓] Network resources
Better Player version
Smartphone (please complete the following information):
First of all, my compliments for this initiative! 🎉👏
Cache feature on iOS is built on top of CachingPlayerItem, which is sort of a discoutinued repo
https://github.com/neekeetab/CachingPlayerItem
Given the mood of this repo is to reignite betterplayer and become the goto reference for it, it would make sense to integrate CachingPlayerItem as source file and update/mantain it as well. At the end, it is just a single class with MIT license.
Note: it would be much appreciated if international english will be used as the language for the repository. The majority of the community is not familiar with chinese.
Hello guys! I’ve seen this initiative for a while and was wondering what its roadmap for the near future?
I see that some prs have been merged but it looks more like a way to collect community-given fixes in one place, rather than an active project meant to provide a feaures-rich stable production ready plugin.
Most of users turned to betterplayer for the cache feature, but now this is going to land soon to video_player flutter/packages@92ce9db
We are seriously thinking to add precache to video_player and stay stick with it.
There are some other initiatives but they dont rely on android/ios native players, which means that it is much harder for them to work well on all devices and to be well mantained over time. So honestly we still consider video_player and plugins built on top of it as the goto solution for enterprise grade usage.
What’s your thought?
History check
I check issue and cannot find for this issue.
Describe the bug
A clear and concise description of what the bug is.
To Reproduce
Steps to reproduce the behavior:
*Example code
@override
void initState() {
super.initState();
episodeHistoryBox = Hive.box(episodeBox);
FlutterDownloader.registerCallback(downloadCallback, step: 1);
getData();
betterPlayerConfiguration = BetterPlayerConfiguration(
startAt: Duration(seconds: time),
allowedScreenSleep: false,
aspectRatio: 16 / 9,
fit: BoxFit.contain,
autoDetectFullscreenAspectRatio: true,
fullScreenAspectRatio: 16 / 9,
controlsConfiguration: const BetterPlayerControlsConfiguration(
loadingColor: Colors.deepOrange,
progressBarBufferedColor: Colors.red, //very useful
progressBarHandleColor: Colors.blue,
progressBarBackgroundColor: Colors.white,
enableSubtitles: false,
pipMenuIcon: Icons.picture_in_picture,
),
eventListener: (e) async {
e.betterPlayerEventType;
BetterPlayerEventType.progress;
final progress = e.parameters!['progress']! as Duration;
SharedPreferences prefs = await SharedPreferences.getInstance();
int duration = progress.inSeconds;
prefs.setInt('curentTime', duration);
switch (e.betterPlayerEventType) {
case BetterPlayerEventType.progress:
final progress = e.parameters!['progress']! as Duration;
SharedPreferences prefs = await SharedPreferences.getInstance();
int duration = progress.inSeconds;
prefs.setInt('curentTime', duration);
break;
default:
break;
}
},
);
}
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Flutter doctor
Please add flutter doctor output here.
Better Player version
Smartphone (please complete the following information):
Additional context
Add any other context about the problem here.
There is issue with hls and dash audio track selection nothing selected while changing audiotrackselection
demo 中 hls_subtitles_page.dart
BetterPlayerDataSource dataSource = BetterPlayerDataSource(
BetterPlayerDataSourceType.network,
Constants.hlsPlaylistUrl,
useAsmsSubtitles: true);
需要改成
BetterPlayerDataSource dataSource = BetterPlayerDataSource(
BetterPlayerDataSourceType.network,
Constants.hlsPlaylistUrl,
videoFormat: BetterPlayerVideoFormat.hls,
useAsmsSubtitles: true);
怎么没有内部判断url是不是hls?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.