Как использовать библиотеку Xamarin.Forms MediaManager с MVVM для воспроизведения видео на YouTube - PullRequest
0 голосов
/ 15 ноября 2018

Я пытаюсь заставить библиотеку MediaManager воспроизводить пару видео с YouTube с использованием подхода MVVM.

Моя идея состоит в том, чтобы иметь один вид, в котором изначально загружается видео, как только пользователь посмотрел первыйзагруженное видео он может нажать кнопку, чтобы увидеть другое видео в том же виде.

Я не могу найти много примеров в интернете, связанных с тем, как сделать это с помощью MVVM, каждый найденный пример использует codebehindподход, но мое приложение создано в полном MVVM, поэтому мне нужно, чтобы оно работало так.

Это то, что я уже сделал.

XAML

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:behaviors="clr-namespace:Behaviors;assembly=Behaviors"
             xmlns:mediamanager="clr-namespace:Plugin.MediaManager.Forms;assembly=Plugin.MediaManager.Forms"
             x:Class="VideoView"
             BindingContext="{Binding VideoViewModel, Source={StaticResource ServiceLocator}}">

    <ContentPage.Behaviors>
        <behaviors:EventHandlerBehavior EventName="Appearing">
            <behaviors:InvokeCommandAction Command="{Binding PageAppearingCommand}" />
        </behaviors:EventHandlerBehavior>
    </ContentPage.Behaviors>

    <StackLayout Margin="10,60,10,0">

        <Label x:Name="LblMsg"/>

        <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <mediamanager:VideoView x:Name="TrainingVideoPlayer"
                                    AspectMode="AspectFill"
                                    HorizontalOptions="FillAndExpand"
                                    VerticalOptions="FillAndExpand" />
            <StackLayout VerticalOptions="End" HorizontalOptions="FillAndExpand">
                <ProgressBar x:Name="progress" HeightRequest="10" Progress="{Binding ProgressStatus, Mode=TwoWay}" />
                <StackLayout Orientation="Horizontal" HorizontalOptions="CenterAndExpand" Spacing="10" VerticalOptions="End">
                    <Image x:Name="ImgPlay"
                           Source="video_play.png"
                           HorizontalOptions="Center">
                        <Image.GestureRecognizers>
                            <TapGestureRecognizer Command="{Binding PlayTappedCommand}" NumberOfTapsRequired="1" />
                        </Image.GestureRecognizers>
                    </Image>
                    <Image x:Name="ImgPause"
                           Source="video_pause.png"
                           HorizontalOptions="Center">
                        <Image.GestureRecognizers>
                            <TapGestureRecognizer Command="{Binding PauseTappedCommand}" NumberOfTapsRequired="1" />
                        </Image.GestureRecognizers>
                    </Image>
                    <Image x:Name="ImgStop"
                           Source="video_stop.png"
                           HorizontalOptions="Center">
                        <Image.GestureRecognizers>
                            <TapGestureRecognizer Command="{Binding StopTappedCommand}" NumberOfTapsRequired="1" />
                        </Image.GestureRecognizers>
                    </Image>
                </StackLayout>
           </StackLayout>
        </Grid>

        <Button x:Name="BtnNext" Command="{Binding NextCommand}"/>

    </StackLayout>

</ContentPage>

ViewModel

public class VideoViewModel : AppBaseViewModel
{

    //Commands
    public ICommand PageAppearingCommand { get; set; }
    public ICommand PlayTappedCommand { get; set; }
    public ICommand PauseTappedCommand { get; set; }
    public ICommand StopTappedCommand { get; set; }
    public ICommand NextCommand { get; set; }

    //Fields
    private double _progressStatus;
    private string youtubevideourl;

    //Properties
    public double ProgressStatus
    {
        get => _progressStatus;
        set
        {
            if (Set(ref _progressStatus, value))
            {
                RaisePropertyChanged(() => ProgressStatus);
            }
        }
    }

    public VideoViewModel()
    {
        PageAppearingCommand = new Command(OnPageAppearing);
        PlayTappedCommand = new Command(OnImgPlay_Tapped);
        PauseTappedCommand = new Command(OnImgPause_Tapped);
        StopTappedCommand = new Command(OnImgStop_Tapped);
        NextCommand = new Command(OnBtnNext_Click);

        youtubevideourl = "https://urloftheyoutubevideo";
    }

    private async void OnPageAppearing()
    {
        await CrossMediaManager.Current.Stop();

        //Sets the videoplayer events to control playback status
        CrossMediaManager.Current.PlayingChanged += VideoPlayer_PlayingChanged;
        CrossMediaManager.Current.MediaFinished += VideoPlayer_MediaFinished;
    }

    private async void OnImgPlay_Tapped()
    {
        await CrossMediaManager.Current.Play(youtubevideourl, MediaFileType.Video);
    }

    private async void OnImgPause_Tapped()
    {
        await CrossMediaManager.Current.Pause();
    }

    private async void OnImgStop_Tapped()
    {
        await CrossMediaManager.Current.Stop();
    }

    private void VideoPlayer_PlayingChanged(object sender, PlayingChangedEventArgs e)
    {
        Device.BeginInvokeOnMainThread(() =>
        {
            ProgressStatus = e.Progress;
        });
    }

    private void VideoPlayer_MediaFinished(object sender, MediaFinishedEventArgs e)
    {
        //Some logic
    }

    private async void OnBtnNext_Click()
    {
        //logic to load the next video url
    }
}

Используя этот код, я могу выполнить методы воспроизведения / паузы / остановки MediaManager, но в View ничего не происходит, я даже не могу увидеть 1 секунду видео на YouTube.

Буду признателен за вашу помощь

Примечание. Я установил пакет nuget MediaManager в свои три проекта: библиотеку Android, iOS и NetStandard

Примечание 2. Одно из моих требованийчтобы максимально гарантировать, что пользователь просмотрел все видео перед переходом к следующему (значение будет сохранено во внешней БД), поэтому любое решение, отличное от этого, должно соответствовать этому требованию

...