setDataSource failed con Xamarin Forms MediaElement - xamarin.forms

I am trying to play youtube / vimeo videos using MediaElement from Xamarin.CommunityToolkit. Well: I always get, on Android, the error setDataSource failed: status = 0x80000000 when adding the url of a youtube video to the MediaElement Source.
Permissions for Android.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Permissions for iOS.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
In iOS, the playback interface opens but I never get to play the video.
I also get this error from Android
enter image description here

I search some info and try to play Youtube video in MediaElement, but find you can not play it directly.
I find another way to do, you can install YoutubeExplode, convert that youtube video url into stream.
<ContentPage
x:Class="mediasample.MainPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="clr-namespace:Xamarin.CommunityToolkit.UI.Views;assembly=Xamarin.CommunityToolkit">
<xct:MediaElement
x:Name="mediasource"
AutoPlay="True"
ShowsPlaybackControls="True"
VerticalOptions="FillAndExpand" />
public MainPage()
{
InitializeComponent();
GetVideoContent();
}
private async void GetVideoContent()
{
YoutubeClient youtube = new YoutubeClient();
// You can specify video ID or URL
YoutubeExplode.Videos.Video video = await youtube.Videos.GetAsync("https://www.youtube.com/watch?v=Cld92SD0jrA");
string title = video.Title; // "Downloaded Video Title"
//string author = video.Author; // "Downloaded Video Author"
TimeSpan duration = (TimeSpan)video.Duration; // "Downloaded Video Duration Count"
//Now it's time to get stream :
StreamManifest streamManifest = await youtube.Videos.Streams.GetManifestAsync("https://www.youtube.com/watch?v=Cld92SD0jrA");
IVideoStreamInfo streamInfo = streamManifest.GetMuxedStreams().GetWithHighestVideoQuality();
if (streamInfo != null)
{
// Get the actual stream
System.IO.Stream stream = await youtube.Videos.Streams.GetAsync(streamInfo);
mediasource.Source = streamInfo.Url;
}
}
The screenshot:

Related

Background Audio Media Element Android Xamrian Forms

Ok So I watched this video and it showed me how to do background audio in ios but how does one do the same using the mediaelement control in andriod does anybody have a solution.
https://www.youtube.com/watch?v=1XVjsUO-Ayw
<xct:MediaElement x:Name="mediaElement"
Grid.Row="0"
HeightRequest="500"
AutoPlay="True"
Volume="1"
ShowsPlaybackControls="True"
VerticalOptions="FillAndExpand"
/>
In IOS am placing
public void EnableBackgroundAudioPlaying()
{
var currentStatus = AVAudioSession.SharedInstance();
currentStatus.SetCategory(AVAudioSessionCategory.Playback);
currentStatus.SetActive(true);
}
But when I USE the android simulator the audio disconnects when i press the home button.

Xamarin Forms Shell GotoAsync

I am using the Shell template from VS2019 in a Xamarin Forms app.I have two pages listed in the shell flyout.
<FlyoutItem Title="Home" Icon="icon_about.png">
<ShellContent Route="HomePage" ContentTemplate="{DataTemplate local:HomePage}" />
</FlyoutItem>
<FlyoutItem Title="Logoff time" Icon="icon_about.png">
<ShellContent Route="SecondPage" ContentTemplate="{DataTemplate
local:SecondPage}" />
</FlyoutItem>
Using the hamburger menu I navigate away from the Homepage to another page SecondPage. I have a button on the SecondPage which perform an action and from that action I want to navigate back to the HomePage. When I use this code:
var route = $"{nameof(HomePage)}";
await Shell.Current.GoToAsync(route);
The HomePage shows but there is a back button instead of the hamburger menu. If I tap the hamburger icon the page navigates back to the SecondPage.
How do I navgate from SecondPage to HomePage and show the hamburger icon?
With so little information (not knowing the details of how your navigation is implemented) it's hard to help you. But the first things that come to mind are the following you could try.
Try one of the following for popping the SecondPage and navigating back to:
await Shell.Current.Navigation.PopAsync();
or
await Shell.Current.Navigation.PopModalAsync();
And if you have a navigation bar with a back button that you don't want then try this in the HomePage.xaml
NavigationPage.HasNvaigationBar="False"
or
Shell.NavBarIsVisible="False"
The two
//
before the route will accomplish my aims.This resets the root page apparently so HomePage once again become the root page.
var route = $"//{nameof(HomePage)}"
I have solved this issue in my own project; I wanted this page to show up at the start of the application, using the navigation class to push the screen and then pop it when the user clicks a button. I had the same issue of a back button showing up, instead of the hamburger icon, when moving the user to the HomePage. I hope this helps someone in the future.
Classes are as follows:
public partial class AppShell : Xamarin.Forms.Shell {
public AppShell() {
InitializeComponent();
Routing.RegisterRoute(nameof(ItemDetailPage), typeof(ItemDetailPage));
Routing.RegisterRoute(nameof(NewItemPage), typeof(NewItemPage));
Routing.RegisterRoute(nameof(HomePage), typeof(HomePage));
Routing.RegisterRoute(nameof(NewUserPage), typeof(NewUserPage));
this.Navigation.PushAsync(new NewUserPage());
}
}
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class NewUserPage : ContentPage {
public NewUserPage() {
InitializeComponent();
this.BindingContext = new NewUserViewModel();
Shell.SetNavBarIsVisible(this, false);
}
}
class NewUserViewModel : BaseViewModel {
public NewUserViewModel() {
NewUserClickedCommand = new Command(OnNewUserClicked);
}
public Command NewUserClickedCommand { get; }
private async void OnNewUserClicked() {
await Shell.Current.Navigation.PopAsync();
}
}
And the XAML file for NewUserPage:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Project.Views.NewUserPage">
<ContentPage.Content>
<StackLayout>
<Label Text="This is a page for new users"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
<Button Text="Click for New User" BackgroundColor="{StaticResource Primary}" Command="{Binding NewUserClickedCommand}"></Button>
</StackLayout>
</ContentPage.Content>
</ContentPage>

Xamarin Forms: How to play Video using Plugin.MediaManager.Forms?

I am trying to play a video using Plugin.MediaManager.Forms and I am referring to this blog.
Step 1: Added Plugin.MediaManager and Plugin.MediaManager.Forms.
Step 2: XAML code - Added a VideoView
<?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:local="clr-namespace:VideoPlayerApp"
x:Class="VideoPlayerApp.MainPage"
xmlns:forms="clr-namespace:Plugin.MediaManager.Forms;assembly=Plugin.MediaManager.Forms"
Title="Video Player">
<ContentPage.Content>
<StackLayout>
<Label Text="Xamarin Forms"
FontSize="40"
TextColor="Azure"/>
<Label Text="Video Player Application"
FontSize="58"
TextColor="BlueViolet"/>
<Button x:Name="PlayStopButtonText"
Text="Play"
Clicked="PlayStopButton"
TextColor="BlueViolet"/>
<forms:VideoView HeightRequest="202"
WidthRequest="202"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Step 3: xaml.cs code
public partial class MainPage : ContentPage
{
private string videoUrl = "https://sec.ch9.ms/ch9/e68c/690eebb1-797a-40ef-a841-c63dded4e68c/Cognitive-Services-Emotion_high.mp4";
public MainPage()
{
InitializeComponent();
}
private void PlayStopButton(object sender, EventArgs e)
{
if (PlayStopButtonText.Text == "Play")
{
CrossMediaManager.Current.Play(videoUrl, MediaFileType.Video);
PlayStopButtonText.Text = "Stop";
}
else if (PlayStopButtonText.Text == "Stop")
{
CrossMediaManager.Current.Stop();
PlayStopButtonText.Text = "Play";
}
}
}
But getting error on this step:
Error CS0103 The name 'MediaFileType' does not exist in the current context
Step 4: Also added VideoViewRenderer.Init();in MainActivity.cs, AppDelegate.cs and MainPage.xaml.cs. But getting following error for this initialization.
The name 'VideoViewRenderer' does not exist in the current context
Am I missing something? I checked some other blogs but same error occuring. I have added a sample project here.
Android Options Screenshot:
The blog seems out of date. Part of APIs and methods were obsoleted . You should check the newest docs from https://github.com/martijn00/XamarinMediaManager#usage .
use the following code instead of VideoViewRenderer.Init() ;
CrossMediaManager.Current.Init();
And just need to call the method
CrossMediaManager.Current.Play(videoUrl);
And I checked your demo . You need to update the version of Xamarin.Forms to 4.2.x both in share project and specific platforms(Android and iOS) .Which will match to the version of the plugin.
Don't forget to set the Dex complier to d8 .
Right click your Android project -> Property-> Android Options.

How to intercept WebView Navigating event in ViewModel

My app has a WebView for displaying some contact information. It has a link to a website that I want to load externally using Device.OpenUri(). I'm using FreshMvvm and I want to intercept the Navigating event from the WebView in the ViewModel and cancel the default action which would load the external page into the WebView.
I've tried using the Corcav.Behaviors plugin which does call my ViewModel command:
<WebView
HorizontalOptions="Fill"
VerticalOptions="FillAndExpand"
Source="{Binding WebViewSource}">
<b:Interaction.Behaviors>
<b:BehaviorCollection>
<b:EventToCommand
EventName="Navigating"
Command="{Binding NavigatingCommand}"
CommandParameter="{Binding}"/> <!-- what goes here -->
</b:BehaviorCollection>
</b:Interaction.Behaviors>
</WebView>
But I'm not sure what the CommandParameter should be - I need the URI of the link that was tapped, and I don't know how to then prevent the default behaviour from occurring.
Is this the best approach or should I be looking at an alternative?
Having revisited this recently for another project I stumbled across the answer. The updated XAML is:
<WebView
x:Name="webView"
HorizontalOptions="Fill"
VerticalOptions="FillAndExpand"
Source="{Binding WebViewSource}">
<behaviors:Interaction.Behaviors>
<behaviors:BehaviorCollection>
<behaviors:EventToCommand
EventName="Navigating"
Command="{Binding NavigatingCommand}"
PassEventArgument="True" />
</behaviors:BehaviorCollection>
</behaviors:Interaction.Behaviors>
</WebView>
The code in the ViewModel, that matches the tapped url against a list of valid options before opening the link in the device's browser, is:
public Command<WebNavigatingEventArgs> NavigatingCommand
{
get
{
return navigatingCommand ?? (navigatingCommand = new Command<WebNavigatingEventArgs>(
(param) =>
{
if (param != null && -1 < Array.IndexOf(_uris, param.Url))
{
Device.OpenUri(new Uri(param.Url));
param.Cancel = true;
}
},
(param) => true
));
}
}
You canĀ“t navigate with a WebView, you must use a custom render (hybridwebview).
Here is an explanation:
https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/custom-renderer/hybridwebview/

Embedded images not showing

This is my page in portable project
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:b="clr-namespace:Corcav.Behaviors;assembly=Corcav.Behaviors"
xmlns:local="clr-namespace:MyMobileApp;assembly=MyMobileApp"
x:Class="MyMobileApp.MainPage"
x:Name="MainPage">
<Image Source="{local:ImageResource myimage.jpg}" />
This is my ImageResourceExtension in same portable project
namespace MyMobileApp
{
[ContentProperty("Source")]
public class ImageResourceExtension : IMarkupExtension
{
public string Source { get; set; }
public object ProvideValue(IServiceProvider serviceProvider)
{
if (Source == null)
return null;
var imageSource = ImageSource.FromResource(Source);
return imageSource;
}
}
}
I have tried to add myimage.jpg as embedded in root of my project and in Resources folder, but no image is shown.
While debugging I see that the returned imageSource is of type Xamarin.Forms.StreamImageSource. How do I check if this is really found?
Can anyone spot the error here?
The correct XAML was to add the app name to the source.
<Image Source="{local:ImageResource MyMobileApp.myimage.jpg}" />
By default the image will have Build Action: None; this needs to be set to Build Action: EmbeddedResource.
Right click on Image > properties > set [Build Action: EmbeddedResource]
[]1
Can you explain the intent of the extension a bit more? Assuming you are putting your images in the proper folders ('Resources' on iOS, 'Resources/Drawable' on Android), then all you need in your XAML is just:
<Image Source="FeaturedAreaMockup.jpg" />
That will find the images in the appropriate folder and show them - why aren't you just doing that? What's the point of the extension?
To read assets/resources folder you need to use:
ImageSource.FromFile("myimage.jpg");'
ImageSource.FromResource uses images included as EmbeddedResource
More here: https://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/images/

Resources