Xamarin UWP MediaPlayer streaming audio from URL starts in middle of file, or doesn't start at all - xamarin

I'm writing a music player app to stream music from Onedrive in Xamarin Forms, which compiles to both Android and UWP. To play a audio file, I pass the URL of the audio file to the native function "Play" which is called via an interface in both the Android and UWP code, which streams the audio file. The Android implementation works perfectly, so I know there is nothing wrong the the audio files or URLs. But for the UWP implementation, larger files sometimes start in the middle of the file, or in one case don't play at all. Again, these all work in Android. Some files work fine though. I'm using MP3 and Flac files, I think I've only had problems with Flac, I assume because they are larger. No errors seem to be thrown as far as I can tell.
The goal here is a to start the audio stream as fast as possible from the URL.
I've tried the most common implementation to stream audio to UWP MediaPlayer that I've found, which is in the code below, as well as using a BackgroundDownloader as a source for MediaPlayer. I've also tried downloading the file beforehand, which takes forever and I'd like to avoid.
[assembly: Dependency(typeof(CloudPlayer.UWP.PlayMusic_UWP))]
namespace CloudPlayer.UWP
{
public class PlayMusic_UWP : PlayMusic
{
MediaPlayer mediaPlayer { get; set; }
public PlayMusic_UWP()
{
mediaPlayer = new MediaPlayer();
}
public void Play(string filePath)
{
mediaPlayer.Source = MediaSource.CreateFromUri(new Uri(filePath));
mediaPlayer.Play();
}
}
}

Related

Xamarin XCT Media Element not playing recorded audio on Android

I am using the AudioRecorder Plugin to record audio and then save it / play it back using the XCT Media element control.
Working fine on iPhone, however on Android it's not playing back the audio at all - either locally or from a URL.
I've taken a copy of the Xamarin sample project (https://github.com/xamarin/xamarin-forms-samples/tree/main/UserInterface/MediaElementDemos) and replaced the URL in the PlayWebAudioPage with the link to my recorded Audio file and it just doesn't play on Android.
Any ideas on how to investigate this further / fix?
The file plays fine on iPhone, on the computer web browser, VLC etc.

Is there a way to use libvlc / libvlcsharp to non interactively transcode or compress a video on iOS?

I am using libVLCSharp (Xamarin bindings to the libvlc library) for video playback. I am adding a feature to transcode / compress downloaded videos to the local filesystem. Normally I'd use mobile-ffmpeg for this, but since internally VLC uses ffmpeg with different build configurations, ffmpeg transcoding does not work - android it crashes the app, ios returns a 'Invalid data found when processing input' error message when attempting to convert. The code works fine when libvlcsharp is uninstalled and there is only one instance of the ffmpeg library being used.
So, I'm looking for video compression / transcode options for Xamarin.iOS.
I've looked into the docs for libvlcsharp and it sounds like we can transcode, but it's somewhat vague on how to do that:
https://github.com/videolan/libvlcsharp/blob/3.x/docs/how_do_I_do_X.md
How do I do transcoding?
Pretty similarly to how you would do it from the CLI. Read https://wiki.videolan.org/Transcode/ and try media options with Media.AddOption.
In my case, I'd like to transcode non-interactively / in the background of the app. There is a 'dummy' option in the command line interface for doing this, so I was wondering how we'd do this from libvlc / libvlcsharp.
So far, my code from these docs looks like this:
using(var vlc = new LibVLC())
{
Media media = new Media(vlc, source, FromType.FromLocation);
media.AddOption($":sout=#transcode{{vcodec=h264,venc=x264{{cfr=40}},vb=2048,scale=auto,acodec=mp4a,ab=96,channels=2,samplerate=44100}}:std{{access=file,mux=ts,dst={destination}}}");
media.AddOption("dummy");
//How do I start the transcoding non interactively??
}
As replied on the libvlc discord server, when you are transcoding a video, it is not displayed at all and you just don't need to create a VideoView, the MediaPlayer alone is enough.
The rest is finding the correct transcoding options, and you already found the correct wiki page for that.

Xamarin Live Player crashes when loading a bitmap, but it runs fine via USB connection

I've been following the examples for using SkiaSharp with Xamarin Forms, particularly the section on using bitmaps. I'm doing this in Microsoft Visual Studio 2017 version 15.9.11. I'm only targeting Android currently.
This page https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/basics/bitmaps has a section on Loading a Bitmap Resource, where the bitmap is an embedded image resource in the project.
So, we add the image and make it type 'embedded resource'
and then run the example code to simply display the image on the canvas.
string resourceID = "SkiaTest.Media.monkey.png";
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream(resourceID))
{
resourceBitmap = SKBitmap.Decode(stream);
}
All pretty simple, and it works fine if I run the code on my phone if it is connected via USB in the standard way (a Sony Z5) so the second in the list here, not the Player:
Here it is working via USB:
But if I try and use Xamarin Live Player (the first in the list above) then it crashes on this line:
using (Stream stream = assembly.GetManifestResourceStream(resourceID))
Note that the app runs fine in Live Player if I don't try and load the bitmap, it's only that line that triggers the crash, and only in Live Player.
So I wonder if anyone has any ideas what could be causing Live Player to fail over this issue? Is the resource not being copied to the phone? Does Live Player just not support this type of activity?
The reason you are facing this issue is that Embedded Resources are not yet supported by Xamarin Live player which is causing this exception.
More details can be found in the Troubleshooting Xamarin Live Player document.

Android MediaPlayer Internal subtitles

I need to show internal subtitles with android MediaPlayer.
I am playing a .ts stream, subtitles are coming on a seperate stream with DVB sub codec.
Currently working on Android 4.2.2, DVB sub is not supported with native media player.
Any Alternative?
You can take a look at Google's open source video player https://github.com/google/ExoPlayer
They don't have DVB, but you can either add your own parser or if you already have it somewhere, then just plug it to the player.
Otherwise, if you want to do it with MediaPlayer, then you need to keep track of current playback time and display the subtitles on top in a separate view.

Detect application launch from Universal Volume Control

I have an application, targeting mango devices, which plays music via a BackgroundAudioAgent. As such it integrates with the universal volume control (UVC).
Is there a way to detect when the application is launched by tapping the artists details in the UVC?
Alternatively, is there a way to set a deep link for the UVC to use?
I want this so that I can take the user to the "Now playing" page, rather than the main page, when the app is launched via the UVC.
Update
This also affects launching the app from the now playing tile in the Music & Video hub as the BackgroundAudioPlayer automatically integrates with this part of the hub.
Using MediaHistory Zune Hub integration solves this problem. It also passes the Marketplace Test Kit capability test step in the RC SDK, so that’s a good sign.
If you start from the example on MSDN, calling the following code from GetNextTrack() and GetPreviousTrack() in the background audio agent means that when you click UVC or Zune Now Playing you can get back the navigation query string you specify here…
private AudioTrack ChangeTrack()
{
AudioTrack track = _playList[currentTrackNumber];
IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication();
Stream s = isoStore.OpenFile("ApplicationIcon.png", FileMode.Open);
MediaHistoryItem nowPlaying = new MediaHistoryItem();
nowPlaying.Title = "Background Audio is playing!";
nowPlaying.ImageStream = s;
nowPlaying.PlayerContext.Add("keyString", track.Title);
MediaHistory.Instance.NowPlaying = nowPlaying;
return track;
}

Resources