Sometimes, as developers and tech enthusiasts, we wonder why certain tools or languages are chosen for developing a particular app. One such question that has aroused our interest is why the Google Team, mainly known for Android, decided to use Flutter to develop the YouTube Create app, as tweeted on Flutter’s official handle. This blog post will walk you through this interesting puzzle, exploring some of Flutter’s features that Google[might have used to create] the YouTube Create app, which is not a “pure Flutter app”, highlighting the potential benefits Flutter brings to the table.
Selecting a framework to build an application is like selecting the right type of fuel for a car race. The speed, power, and overall performance of the car depend heavily on the fuel it uses.
In this case, we're looking at why Google chose Flutter, for its YouTube Create app. The reason behind this can be Flutter's core principles – beautiful UIs, native performance, and the ability to communicate with native platform-specific code via the use of platform channels. Flutter's native compilation to ARM and x64 machine code promises high performance for both CPU and GPU tasks essential for a video editing application. This capability directly supports intensive tasks such as applying filters or transitions, rendering previews, and exporting the final edited video. These principles simplify the complexity that usually underlies cross-platform development for any wonderful app.
Flutter framework relies on Dart, a programming language praised for its simplicity and powerful functionality. Together, they're changing the game in the world of cross-platform application design. The potential of this combination can also possibly be harnessed to create an optimal user interface experience for the YouTube Create app.
Looking from an overall perspective it seems Flutter can efficiently manage this kind of app with a relevant structure. Architecture plays a big role in any application development. It aims to keep different parts of the code separate, thus making it easier to manage, scale, and update.
Building a video editing app like YouTube Create in Flutter requires careful consideration of state management, some of the approaches that could fit well here:
The Provider + ChangeNotifier approach is relatively simple and easy to understand. It's officially recommended by the Flutter team.
With this approach, you write your business logic in classes that extend ChangeNotifier
, and expose those classes to your widget tree using Provider
. You can notify listeners from ChangeNotifier
when there's a change in the state so widgets can rebuild themselves accordingly.
Let's delve deeper into the usage of Provider
and ChangeNotifier
in the context of a video editing application, say a feature from the YouTube Create app that allows users to trim a video.
Firstly, imagine we have a Video
model:
1class Video { 2 final String id; 3 final String url; 4 Duration start; 5 Duration end; 6 7 Video({ 8 required this.id, 9 required this.url, 10 required this.start, 11 required this.end, 12 }); 13} 14
Next, we would create a ChangeNotifier
that's going to handle the state of the Video
:
1class VideoEditingState with ChangeNotifier { 2 Video _video; 3 4 VideoEditingState(this._video); 5 6 Video get video => _video; 7 8 void trimVideo(Duration start, Duration end) { 9 _video.start = start; 10 _video.end = end; 11 notifyListeners(); 12 } 13} 14
Here, VideoEditingState
is managing the state of a Video
. Whenever the user trims the video, trimVideo()
is called, which modifies the start
and end
fields of the Video
object and then calls notifyListeners()
to inform the widgets that are consuming this ChangeNotifier
that they should rebuild.
Now let's see how to provide the VideoEditingState
to the widget tree and use it. Use the ChangeNotifierProvider
to create the state and provide it:
1class MyApp extends StatelessWidget { 2 3 Widget build(BuildContext context) { 4 return MaterialApp( 5 title: 'Youtube', 6 home: ChangeNotifierProvider( 7 create: (_) => VideoEditingState(Video(id: '1', url: '<url>', start: Duration.zero, end: Duration(minutes: 10))), 8 child: VideoEditor(), 9 ), 10 ); 11 } 12} 13
In the VideoEditor
widget, we will use Consumer
to listen to changes in VideoEditingState
:
1class VideoEditor extends StatelessWidget { 2 3 Widget build(BuildContext context) { 4 return Consumer<VideoEditingState>( 5 builder: (context, videoEditingState, _) { 6 return Column( 7 children: <Widget>[ 8 Text('Video start: ${videoEditingState.video.start}'), 9 Text('Video end: ${videoEditingState.video.end}'), 10 RaisedButton( 11 child: Text('Trim video'), 12 onPressed: () => videoEditingState.trimVideo(Duration(minutes: 0), Duration(minutes: 5)), 13 ), 14 ], 15 ); 16 }, 17 ); 18 } 19} 20
In the VideoEditor
, we display the Video
's current start and end times, and when the "Trim video" functionality is used, we call trimVideo()
, which changes the Video
's state and triggers a re-build of Consumer
since it's listening to VideoEditingState
. Thus the displayed start and end times update.
This pattern is particularly suitable for an app where states are likely to change often such as a video editing app. It allows for a clear separation of UI and business logic, resulting in code that's easier to test and maintain.
More powerful and flexible state management, Riverpod. Riverpod has been regarded as the improved version of Provider, as it addresses many weaknesses in Provider (like its tight coupling with the widget tree).
One of the strengths of Riverpod is its flexibility. It allows you to have conditional providers (Providers that return different values based on other providers), and have more control over the lifecycle of your providers.
Riverpod also comes with built-in support for asynchronous programming (through FutureProvider
, StreamProvider
, and StateNotifierProvider
), which could be very useful in a video editing app where we usually have many asynchronous operations.
Both of these state management solutions have their strengths and are widely used in the Flutter community.
Applying the clean architecture in Flutter and using its powerful state management could be a reason why the YouTube Create App boasts smooth operations like project creation, editing, and deletion.
Local data persistence is crucial in video editing apps for several reasons like avoiding data loss, saving user preferences and configurations, and caching. User experience must remain intact while they are editing, trimming, or finalizing their videos at that last moment. For such a secure data-saving feature Flutter can be the saviour.
Flutter aids in local data persistence through several libraries, and they can work harmoniously with any state management pattern and can help in the development of a video editing app:
shared_preferences
plugin, which wraps NSUserDefaults on iOS and SharedPreferences on Android, providing a persistent store for simple data. It could be useful in a video editing application for storing user preferences and settings.Through these libraries, Flutter gives you tremendous power and flexibility to manage local data persistence in a video editing app, ensuring a seamless user experience. Application state, user preferences, and complex project metadata could comfortably be managed and stored across different sessions of the app.
Certainly, Flutter is designed in a way that makes it a fantastic choice for building applications with rich, complex, and compelling 😍 animations and transitions.
Flutter uses the power of Skia Graphics Library and Realtime Renderer Impeller. Impeller precompiles a small and simple set of shaders at Engine build time to avoid compiling at runtime. Skia is responsible for drawing every pixel that you see on the screen. Because Skia is implemented in C/C++, it allows for faster rendering and smooth animations. Skia provides APIs for 2D graphics, including path drawing, images, text, and shaders which can be leveraged for complex animations which we can see at the start when the YouTube Create app launches on the mobile.
Flutter is declarative and reactive. When a widget’s state changes, the widget rebuilds its description, which the Flutter framework diffs against the previous description to determine the minimal changes needed in the render tree to transition from one state to the next. This ensures that Flutter keeps the UI in sync with the state.
Flutter runs at 60 frames per second (fps) or even 120 fps on devices capable of 120Hz updates. Every frame marks the creation of a set of widget trees (an element tree, a render object tree), which get diffed to calculate the update operations to be performed on the widgets. This ensures smooth and jank-free animations because the UI is always in sync with the frame rate.
Flutter's design enables the creation of complex, customized animations through the AnimationController
and Tween
classes. AnimationController
manages the animation, allowing control over its duration and state (started, stopped). It generates a new value for every frame in a defined period. Tween
defines the start and end of an animation range, and an interpolated value within that range can be obtained.
So, in the context of a video editing app, the rich animation capabilities that Flutter offers can be directly leveraged to design fluid and customized animations and transitions, leading to a more immersive and interactive user experience.
The url_launcher package in Flutter is a convenient feature that makes launching URLs (Uniform Resource Locator) straightforward, giving your mobile application a commendable level of connectivity with the web.
Here is a technical overview of how it works:
https://
opens the link in a browser, mailto:
opens the user's email client, tel:
initiates a phone call, etc.url_launcher
interacts with the platform's native code to handle these URL schemes, taking advantage of both Android's and iOS's native capabilities to handle such tasks. This includes checking if the given URL can be handled by any app installed on the device and then opening it using the best available option. So, here they have the YouTube Create app for Android, interaction with the Native code might be creating wonders in the backend while users share the edited video on their YouTube channel via the Create app!!url_launcher
plugin return a Future
, making it compatible with asynchronous programming in Flutter. This ensures that your user interface remains responsive while the plugin awaits the native platform to complete the URL launching process.url_launcher
is cross-platform, meaning it works seamlessly on both Android and iOS devices. This greatly simplifies the development process because you only have to write your URL launching code once.In the case of the YouTube Create video editing app, the url_launcher
package might be providing seamless interaction with browser-based resources, directing users to their YouTube channel pages, among other capabilities, making it a valuable asset to the overall app experience.
The share_plus package in Flutter is a versatile and essential tool, especially in a content creation app like a video editing application. It allows users to share their content, such as edited videos, across different platforms by utilizing the native platform's sharing capabilities.
1// Import the package 2import 'package:share_plus/share_plus.dart';
Here's a brief technical overview:
share_plus
package works consistently across different platforms, including Android, iOS, Windows, Linux, and the web. It enables you to write the sharing code once and have it work across all these platforms.1// You can use the same function to share on both Android and iOS 2Share.share('check out my video https://example.com');
share_plus
can handle multiple types of content, such as text (like a video title or description), links (a URL to the video's location), and even binary files (like the video file itself).1// Share text 2Share.share('Amazing video'); 3 4// Share a link 5Share.share('https://example.com/video.mov');
share_plus
return a Future
. This means that they are non-blocking and won’t hang the UI.In a video editing app, using the share_plus
package would enhance the user experience by allowing users to share their edited videos or send them directly to different platforms. This easy export and share functionality could help increase user engagement, making the app more user-friendly and efficient.
1// For sharing files 2Share.shareFiles(['${Directory.systemTemp.path}/video.mov'], text: 'Great Video');
Managing asynchronous tasks in a high-performance app like a video editing application is crucial. Flutter's RxDart and Streams are part of Dart's core library that allows for efficient task management in an asynchronous environment.
Streams are a way of handling asynchronous data sequences, such as user input events or I/O operations. They are especially useful when working with continuous or live data. For instance, in a video editing app, a stream can handle and process video frames in real time.
1// Conceptual example of a single subscription stream 2// that handles video frames for processing 3Stream<VideoFrame> videoFrames = getVideoFramesAsStream(); 4videoFrames.listen((frame) { 5 applyFilterToFrame(frame); 6});
RxDart is a reactive functional programming library for Dart based on ReactiveX - a cross-platform library for handling asynchronous data streams. RxDart does not provide any additional Widgets, but it is meant to be used in conjunction with Flutter's existing ones.
Here's how they contribute effectively:
1// Example of StreamController, Stream and Sink 2final controller = StreamController<int>(); 3final StreamSink<int> input = controller.sink; // Sink 4final Stream<int> output = controller.stream; // Stream
1// Example of BehaviorSubject (keeps the latest item and emit to new subscribers) 2var subject = BehaviorSubject<int>(); 3subject.add(1); 4subject.stream.listen((value) => print("First Subscriber: $value")); // will print 1 5subject.add(2); 6subject.stream.listen((value) => print("Second Subscriber: $value")); // will print 2
1Observable.range(1, 5) 2 .map((value) => value * value) 3 .listen(print); // prints 1, 4, 9, 16, 25
In the context of a video editing app to be developed in Flutter, operations such as importing clips, editing them, applying filters, and exporting the final video can be handled efficiently using RxDart and Streams. These operations could be processed as data sequences, and through the use of various operators, developers can map out complex workflows, handle errors gracefully, and improve the overall efficiency of the app.
When it comes to why Flutter was possibly chosen for the YouTube Create App, a few speculations can be made:
It’s important to note that all these are educated guesses, and the actual reasons might vary. However, these points reflect the various ways in which Flutter’s features might have been valuable in developing the YouTube Create App. It’s always exciting to see how developers utilize the capabilities of various languages and frameworks., and in this use case, Flutter can be a great fit!
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.