I am trying to write a simple player application using LibVLCSharp and I am wondering how to stop the app when player closes. Currently, it just freezes and doesn't stop the app even though I added SetExitHandler callback.
using System;
using System.Threading;
using LibVLCSharp.Shared;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Core.Initialize();
using var libVlc = new LibVLC();
using var mediaPlayer = new MediaPlayer(libVlc);
libVlc.SetExitHandler(() =>
{
Environment.Exit(1);
});
var media = new Media(libVlc, "v4l2:///dev/video0", FromType.FromLocation);
media.AddOption(":v4l2-standard=ALL :live-caching=300");
mediaPlayer.Play(media);
Thread.Sleep(TimeSpan.FromSeconds(10));
}
}
}
Log after I close the window:
[00007fa164004790] gl gl: Initialized libplacebo v2.72.0 (API v72)
[00007fa17400a7c0] main decoder error: buffer deadlock prevented
[00007fa1600429a0] xcb_window window error: X server failure
The following code example from LibVLCSharp GitHub Page shows how to play the video in a console application.
Core.Initialize();
using var libvlc = new LibVLC(enableDebugLogs: true);
using var media = new Media(libvlc, new Uri(#"C:\tmp\big_buck_bunny.mp4"));
using var mediaplayer = new MediaPlayer(media);
mediaplayer.Play();
Console.ReadKey();
Note the use of Console.ReadKey() to wait for the user to press a key before closing the application and subsequently closing the player.
To exit the application automatically when the video ends, you can use MediaPlayer.EndReached event as shown here:
Core.Initialize();
using var libvlc = new LibVLC(enableDebugLogs: true);
using var media = new Media(libvlc, new Uri(#"C:\tmp\big_buck_bunny.mp4"));
using var mediaplayer = new MediaPlayer(media);
mediaplayer.EndReached += (s, e) => Environment.Exit(0);
mediaplayer.Play();
Console.ReadKey();
Related
I'm trying to play the video stream "https://s2.moidom-stream.ru/s/public/0000000087.m3u8" using LibVlc, but I only get a black screen. Other threads work fine, but I need this particular thread.
code used:
using Android.App;
using Android.OS;
using Android.Widget;
using LibVLCSharp.Shared;
using System;
using System.Linq;
using WebCamTst.Helpers;
namespace WebCamTst
{
[Activity(Label = "PanelActivity")]
public class PanelActivity : Activity
{
LibVLCSharp.Platforms.Android.VideoView videoView;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.videopanel);
videoView = FindViewById<LibVLCSharp.Platforms.Android.VideoView>(Resource.Id.videoView1);
}
protected override void OnResume()
{
base.OnResume();
PlayVideo("https://s2.moidom-stream.ru/s/public/0000000087.m3u8");
}
private void PlayVideo(string url)
{
Core.Initialize();
using (var libVLC = new LibVLC())
using (var mPlayer = new MediaPlayer(libVLC) { EnableHardwareDecoding = true })
{
videoView.MediaPlayer = mPlayer;
var _media = new Media(libVLC, url, FromType.FromLocation);
_media.Parse(MediaParseOptions.ParseNetwork);
mPlayer.Play(_media);
}
}
}
}
but it doesn't work.
Please help!
Please start with one of the official android samples.
It doesn't work because Play() is not a synchronous method. It actually starts the libvlc thread in the background.
This means that your libvlc and your player are disposed too early and your video is stopped immediately.
Other remarks:
You can Dispose() your media immediately after having passed into the media player.
Your call to Parse is useless because it's also asynchronous and isn't required (Play calls it anyway)
In addition to cube45's answer, m3u8 are played differently than regular media...
var libVLC = new LibVLC();
var media = new Media(libVLC, "https://s2.moidom-stream.ru/s/public/0000000087.m3u8", FromType.FromLocation);
await media.Parse(MediaParseOptions.ParseNetwork);
var mp = new MediaPlayer(media.SubItems.First());
mp.Play();
I want to play multiple sounds simultaneously in my Winforms project, but I am not able to add the Windows Media Player as an assembly to my project, because .NET Framework is missing in my Core 6 Project.
The following code should be ported to .NET Core 6:
using System;
using WMPLib;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
var sound1 = new WindowsMediaPlayer();
sound1.URL = #"path of sound1";
var sound2 = new WindowsMediaPlayer();
sound2.URL = #"path of sound2";
Console.ReadLine();
}
}
}
If you want to play multiple sounds simultaneously in .Net 6 Winforms project, you can refer to the following steps:
First doubule-click on the project and open the project file WinFormsApp1.csproj.
Second add the following code in the file:
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
Then we can use the code in Form1.cs:
using System.Windows.Media;
namespace WinFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var sound1 = new MediaPlayer();
sound1.Open(new Uri(#"path of sound1"));
sound1.Play();
var sound2 = new MediaPlayer();
sound2.Open(new Uri(#"path of sound2"));
sound2.Play();
}
}
}
Finally we can play multiple sounds simultaneously.
I don't know either we can create a console app or not for speech recognition(searched for the same but didn't find any answer)and tried this code.
I have this code working in winforms app
but when trying to create this app in console visual studio is giving a very strange error mscorelib.pdb not found.And transferring to a page mscorelib.pdb
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Speech;
using System.Speech.Recognition;
using System.Speech.Synthesis;
using System.Threading;
namespace ConsoleApplication2
{
public class Program
{
public static void Main(string[] args)
{
tester tst = new tester();
tst.DoWorks();
}
}
public class tester
{
SpeechSynthesizer ss = new SpeechSynthesizer();
SpeechRecognitionEngine sre = new SpeechRecognitionEngine();
PromptBuilder pb = new PromptBuilder();
Choices clist = new Choices();
public void DoWorks()
{
clist.Add(new string[] { "how are you", "what is the current time", "open chrome", "hello" });
Grammar gr = new Grammar(new GrammarBuilder(clist));
sre.RequestRecognizerUpdate();
sre.LoadGrammar(gr);
sre.SetInputToDefaultAudioDevice();
sre.SpeechRecognized += sre_recognised;
sre.RecognizeAsync(RecognizeMode.Multiple);
}
public void sre_recognised(object sender, SpeechRecognizedEventArgs e)
{
switch (e.Result.Text.ToString())
{
case "hello":ss.SpeakAsync("Hello shekar");
break;
case "how are you": ss.SpeakAsync("I am fine and what about you");
break;
case "what is the time":ss.SpeakAsync("current time is: " + DateTime.Now.ToString());
break;
case "open chrome":System.Diagnostics.Process.Start("chrome", "wwe.google.com");
break;
default: ss.SpeakAsync("thank you");
break;
}
Console.WriteLine(e.Result.Text.ToString());
}
}
}
here is the snapshot of the error page
I also loaded the given option "Microsoft.symbol.Server", but it is still giving the same output.
EDIT
HERE is the output window
Outputs are of big lengths ,so not being able to show all the outputs ,captured some relevant parts (regret).
You're seeing the debugger issuing a RaceOnRCWCleanup. The reason may be that you are instantiating but not properly cleaning up COM objects created under the hood by SpeechSynthesizer and/or SpeechRecognitionEngine.
At the same time, a Console application is not automatically 'kept alive'. You need to specifically add code to prevent it from exiting immediately.
You need to do 2 things:
Ensure your application stays alive long enough (for example, by adding a Console.ReadLine() statement in the Main method
Make sure that resources are properly cleaned up. Both SpeechRecognitionEngine and SpeechSynthesizer implement IDisposable, so they should be disposed when no longer needed. To do this properly, implement IDisposable in your tester class:
Example:
public class Tester
{
SpeechSynthesizer ss = new SpeechSynthesizer();
SpeechRecognitionEngine sre = new SpeechRecognitionEngine();
public void Dispose()
{
ss.Dispose();
sre.Dispose();
}
}
I am new to selenium, currently exploring on how it works. Started using it for ASP.NET application, i am using C# Selenium driver, IE Driver server ( 32 bit as it's faster than 64 bit)
I navigated to a application there I am clicking a link which should take me to ANOTHER WEBSITE where I have to find a textbox and clear it and enter some text (SendKeys) and then click a button.
When it goes to a another website from main website, It's unable to find the element ( I tried using by.ID and by.Name). I made sure element is available on the webpage. As recommened I used ImplicitlyWait but no luck, tried thread.sleep() no lucK.. Does the test needs to be on the same website which launched initially ?.. Below is my code snippet.. Please help me..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Support.UI;
using System.Threading;
namespace mySelenium
{
class Program
{
private static void Main(string[] args)
{
IWebDriver driver = new InternetExplorerDriver(#"C:\Users\msbyuva\Downloads\IEDriverServer_Win32_2.45.0\");
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
driver.Navigate().GoToUrl("http://MyorgName.org/Apps/Sites/2015/login.aspx");
IWebElement userNameTxtBox = driver.FindElement(By.Id("ContentPlaceHolder1_Login1_UserName"));
userNameTxtBox.SendKeys("MSBYUVA");
IWebElement passwordTxtBox = driver.FindElement(By.Id("ContentPlaceHolder1_Login1_Password"));
passwordTxtBox.SendKeys("1234");
var myButton = driver.FindElement(By.Id("ContentPlaceHolder1_Login1_LoginButton"));
myButton.Click();
var EMailLink = driver.FindElement(By.LinkText("Email Testing Link"));
EMailLink .Click();
//Thread.Sleep(10000);
// -- HERE IT IS THROWING ERROR (ANOTHER WEBSITE AFTER CLICKING HYPERLINK)
var toEmailAddress = driver.FindElement(By.Name("ctl00$ContentPlaceHolder1$txtTo"));
toEmailAddress.Clear();
toEmailAddress.SendKeys("msbyuva#gmail.com");
var chkEmailAttachment = driver.FindElement(By.Name("ctl00$ContentPlaceHolder1$ChkAttachMent"));
chkEmailAttachment.Click();
var sendEmailButton = driver.FindElement(By.Id("ctl00_ContentPlaceHolder1_BtnSend"));
sendEmailButton.Click();
}
}
}
You need to switchTo newly opened window and set focus to it in order to send any commands to it
string currentHandle = driver.CurrentWindowHandle;
driver.SwitchTo().Window(driver.WindowHandles.ToList().Last());
After you done with newly opened window do(as need)
driver.Close();
driver.SwitchTo().Window(currentHandle );
More perfectly use PopupWindowFinder class
string currentHandle = driver.CurrentWindowHandle;
PopupWindowFinder popUpWindow = new PopupWindowFinder(driver);
string popupWindowHandle = popUpWindow.Click(EMailLink );
driver.SwitchTo().Window(popupWindowHandle);
//then do the email stuff
var toEmailAddress = driver.FindElement(By.Name("ctl00$ContentPlaceHolder1$txtTo"));
toEmailAddress.Clear();
toEmailAddress.SendKeys("msbyuva#gmail.com");
var chkEmailAttachment = driver.FindElement(By.Name("ctl00$ContentPlaceHolder1$ChkAttachMent"));
chkEmailAttachment.Click();
var sendEmailButton = driver.FindElement(By.Id("ctl00_ContentPlaceHolder1_BtnSend"));
sendEmailButton.Click();
}
}
}
//closing pop up window
driver.Close();
driver.SwitchToWindow(currentHandle);
Monotouch 5.0.2.
Running the simple code below I get this in the output panel:
objc[20283]: Object 0x9c08110 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
objc[20283]: Object 0x9c07840 of class __NSCFData autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
Which NSStrings are leaking here and why? It seems to be enough to just create a new Uri() and a new WebClient() objetc. The event handler doesn't even have to be attached.
using System;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using System.Net;
using System.IO;
namespace DownloadTest
{
[Register ("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate
{
UIWindow window;
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
window = new UIWindow (UIScreen.MainScreen.Bounds);
UIButton btn = UIButton.FromType (UIButtonType.RoundedRect);
btn.Frame = new System.Drawing.RectangleF (40, 40, 100, 30);
btn.TouchUpInside += delegate {
// These two lines seem to caus the leak.
Uri uri = new Uri ("http://silverlightinaction.com/video3.wmv");
WebClient webClient = new WebClient ();
// This line does not matter, the info about the leaking NSString alsp appears without an event being attached.
webClient.OpenReadAsync (uri);
};
window.AddSubview (btn);
window.MakeKeyAndVisible ();
return true;
}
void HandleWebClientOpenReadCompleted (object sender, OpenReadCompletedEventArgs e)
{
using (var pool = new NSAutoreleasePool())
{
using (Stream stream = e.Result)
using (FileStream fileStream = File.OpenWrite(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "download.bin")))
{
stream.CopyTo (fileStream, 30000);
stream.Close ();
fileStream.Close ();
}
}
}
}
}
This is a MonoTouch bug. WebClient uses Thread which does not automagically creates an NSAutoreleasePool around the code being executed (e.g. like you did in your delegate). That can cause some leaks - just like you're seeing with the warning messages.
Note that using (threads from) ThreadPool is already ensuring that an NSAutoreleasePool covers the thread's execution.
I created a new class deriving from WebClient and overrode the "OnDownloadedCompleted" and created my own pool within a using block. This seemed to get rid of the debug messages, not sure if it's the perfect fix though.
using(var a = new MonoTouch.Foundation.NSAutoreleasePool())
{
base.OnDownloadDataCompleted (args);
}