I am implementing a media player app with Bluetooth connectivity using Prism and Unity.
The application flow I am working with goes as follows:
- User issues a command on a remote device (phone/tablet)
- Desktop application receives the
Play
command via a Bluetooth service - A higher level service processes the metadata and tells the
VideoPlaybackViewModel
to begin playing
What I have so far
The Bluetooth service has not been implemented yet because I want to finish the other elements first. When it comes time to do that, I will follow this example (https://github.com/saramgsilva/BluetoothSampleUsing32feet.Net).
Following this question (MVVM pattern violation: MediaElement.Play()),
I have implemented VideoPlaybackView
and VideoPlaybackViewModel
.
VideoPlaybackView
:
<UserControl x:Class="Views.VideoPlaybackView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ia="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
x:Name="MediaService">
<ia:Interaction.Triggers>
<ia:EventTrigger EventName="Loaded">
<ia:InvokeCommandAction Command="{Binding LoadedCommand}" CommandParameter="{Binding ElementName=MediaService}" />
</ia:EventTrigger>
</ia:Interaction.Triggers>
<Grid>
<MediaElement
x:Name="VideoPlayer"
Source="{Binding VideoSource}" />
</Grid>
</UserControl>
VideoPlaybackViewModel
:
public class VideoPlaybackViewModel : BindableBase {
private Uri _videoSource;
public IMediaService MediaService { get; private set; }
public Uri VideoSource {
get => _videoSource;
set => SetProperty(ref _videoSource, value);
}
private DelegateCommand<IMediaService> _loadedCommand;
public DelegateCommand<IMediaService> LoadedCommand {
get {
if (_loadedCommand == null) {
_loadedCommand =
new DelegateCommand<IMediaService>((mediaService) => { MediaService = mediaService; });
}
return _loadedCommand;
}
}
}
These are initialized when the VideoPlaybackModule
is loaded:
public class VideoPlaybackModule : IModule {
private IUnityContainer _container;
private IRegionManager _regionManager;
public VideoPlaybackModule(IUnityContainer container, IRegionManager regionManager) {
_container = container;
_regionManager = regionManager;
}
public void Initialize() {
_regionManager.RegisterViewWithRegion("MainRegion", typeof(VideoPlaybackView));
}
}
I am using modules because I want to learn them.
The goal
What I would like is to have a controller of some sort that can receive the events from the bluetooth service,
parse the metadata, update the MediaElement.Source
, and somehow send a command to the VideoPlayerViewModel
to actually play the video.
Attempts
I have seen the idea of implementing a controller, but I am not sure how I am supposed to initialize it. I come up
with the following questions:
- How do I hook up the controller to respond to the Bluetooth commands from the Bluetooth service?
- Should the controller keep a reference to VideoPlaybackViewModel
in order to execute commands?
I think a service could be applicable here as well. If, for example, I created a VideoPlaybackService
, how would this service be used? Similar to the controller idea, it would need to handle the processing of metadata before sending the command to VideoPlayerViewModel
.
How can I use Prism and Unity to implement this pattern?