I want to use a MediaPlayer for videos and pictures with the MediaElement. I have already done tests, the MediaElement can also display pictures.
Currently I have the problem that the MediaElement seems to open twice.
Here is the example code:
XAML:
<Window x:Class="TestMediaElement.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestMediaElement"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Margin="10">
<MediaElement Name="mediaPlayer" MediaOpened="media_MediaOpened" LoadedBehavior="Play" UnloadedBehavior="Manual"/>
</Grid>
</Window>
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace TestMediaElement
{
public partial class MainWindow : Window
{
int currentMediaIndex = 0;
string[] Documents;
public MainWindow()
{
InitializeComponent();
Documents = System.IO.Directory.GetFiles("C:/Users/Feller/Desktop/Test/");
Uri first = new Uri(Documents[0], UriKind.RelativeOrAbsolute);
mediaPlayer.Source = first;
mediaPlayer.MediaOpened += media_MediaOpened;
}
private void media_MediaOpened(object sender, RoutedEventArgs e)
{
Console.WriteLine("Video opened");
}
}
}
Another problem is that images close automatically after about 5 seconds.
Can anyone help me with these problems?
Thank you very much!
MediaOpened event is subscribed twice. Either remove from the xaml or remove from code.
//mediaPlayer.MediaOpened += media_MediaOpened;
Related
In the file MainWindow.xaml.cs in the method TakeScreenShot i'm getting exception on the
line :
var executedScript = WebView.EvaluateScriptAsync(jsString).Result.Result;
System.Exception
HResult=0x80131500
Message=Unable to execute javascript at this time, scripts can only be executed within a V8Context. Use the IWebBrowser.CanExecuteJavascriptInMainFrame property to guard against this exception. See https://github.com/cefsharp/CefSharp/wiki/General-Usage#when-can-i-start-executing-javascript for more details on when you can execute javascript. For frames that do not contain Javascript then no V8Context will be created. Executing a script once the frame has loaded it's possible to create a V8Context. You can use browser.GetMainFrame().ExecuteJavaScriptAsync(script) or browser.GetMainFrame().EvaluateScriptAsync to bypass these checks (advanced users only).
Source=CefSharp
StackTrace:
at CefSharp.WebBrowserExtensions.ThrowExceptionIfCanExecuteJavascriptInMainFrameFalse()
at CefSharp.WebBrowserExtensions.EvaluateScriptAsync(IChromiumWebBrowserBase browser, String script, Nullable`1 timeout, Boolean useImmediatelyInvokedFuncExpression)
at Web_Browser_WPF.MainWindow.TakeScreenShot(String siteUrl) in D:\Csharp Projects\Web Browser WPF\MainWindow.xaml.cs:line 47
at Web_Browser_WPF.MainWindow.ChromiumWebBrowser_LoadingStateChanged(Object sender, LoadingStateChangedEventArgs e) in D:\Csharp Projects\Web Browser WPF\MainWindow.xaml.cs:line 64
at CefSharp.Wpf.ChromiumWebBrowser.CefSharp.Internals.IWebBrowserInternal.SetLoadingStateChange(LoadingStateChangedEventArgs args)
at CefSharp.Internals.ClientAdapter.OnLoadingStateChange(ClientAdapter* , scoped_refptr* browser, Boolean isLoading, Boolean canGoBack, Boolean canGoForward)
and then if i mark as comment not to use the part of the jString and executedScript and not assigning to the height then i'm getting null exception on the line :
bitmap.Save(#"d:\Test.jpg");
because WebView is null.
so i'm stuck here.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using CefSharp;
using CefSharp.OffScreen;
namespace Web_Browser_WPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
WindowStartupLocation =
System.Windows.WindowStartupLocation.CenterScreen;
}
private void TakeScreenShot(string siteUrl)
{
CefSharp.OffScreen.ChromiumWebBrowser WebView = new CefSharp.OffScreen.ChromiumWebBrowser(siteUrl);
int width = 1280;
int height = 1480;
string jsString = "Math.max(document.body.scrollHeight, " +
"document.documentElement.scrollHeight, document.body.offsetHeight, " +
"document.documentElement.offsetHeight, document.body.clientHeight, " +
"document.documentElement.clientHeight);";
var executedScript = WebView.EvaluateScriptAsync(jsString).Result.Result;
height = Convert.ToInt32(executedScript);
WebView.Size = new System.Drawing.Size(width, height); //size;
Thread.Sleep(500);
// Wait for the screenshot to be taken.
var bitmap = WebView.ScreenshotOrNull();
bitmap.Save(#"d:\Test.jpg");
bitmap.Dispose();
}
private void ChromiumWebBrowser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
{
if(!e.IsLoading)
{
TakeScreenShot("https://ims.gov.il/he/RadarSatellite");
}
}
}
}
The xaml code
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:cef="clr-namespace:Web_Browser_WPF"
xmlns:Wpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf" x:Class="Web_Browser_WPF.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="720" Width="1024">
<Grid>
<Wpf:ChromiumWebBrowser HorizontalAlignment="Left" Margin="363,181,0,0" VerticalAlignment="Top"/>
<Wpf:ChromiumWebBrowser x:Name="chromiumBrowser1"/>
<Wpf:ChromiumWebBrowser Address="https://ims.gov.il/he/RadarSatellite" LoadingStateChanged="ChromiumWebBrowser_LoadingStateChanged" />
</Grid>
</Window>
I have some uwp application, where several videos are played simultaneously. I thought it might be a good idea to use 1 media source to improve performance. But I'm not sure why this idea doesn't work.
MainPage.xaml:
<Page
x:Class="UWP_OneMediaSourceForSeveralPlayers.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWP_OneMediaSourceForSeveralPlayers"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
Loaded="Page_Loaded">
<StackPanel Orientation="Vertical" Background="Yellow" Height="400" Width="200">
<MediaPlayerElement x:Name="Player1" Height="200" Width="200" />
<MediaPlayerElement x:Name="Player2" Height="200" Width="200" />
</StackPanel>
</Page>
MainPage.xaml.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Media.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
namespace UWP_OneMediaSourceForSeveralPlayers
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
var uri = new Uri(BaseUri, "/Assets/Videos/video.mp4");
var mediaSource = MediaSource.CreateFromUri(uri);
Player1.Source = mediaSource;
Player2.Source = mediaSource;
Player1.MediaPlayer.Play();
Player2.MediaPlayer.Play();
}
}
}
That's what I see:
So, looks like the first video is loaded. But not the second...
NOW question: why I can not use 1 media source for 2 players? How to make it work? Or do you have any other idea how to run the same file in several players?
P.S. creating 2 media sources from URI is not a good solution for me, because my app can have a lot (10+) videos running at the same time. If I create a media source for each player it will hurt performance.
So what you can actually do here is share a MediaPlayer between the two MediaPlayerElement instance.
private void Page_Loaded(object sender, RoutedEventArgs e)
{
var uri = new Uri(BaseUri, "/Assets/Videos/video.mp4");
var mediaSource = MediaSource.CreateFromUri(uri);
var player = new MediaPlayer
{
Source = new MediaPlaybackItem(mediaSource)
};
Player1.SetMediaPlayer(player);
Player2.SetMediaPlayer(player);
player.Play();
}
If you don't require the transport controls from MediaPlayerElement, it's probably better to use MediaPlayerPresenter instead.
I need to expand an existing Run to include some new text (with different formatting) without adding an additional paragraph. Is this possible?
When I inspect the properties of the FirstBlock on the Document, I do not see any property which allow me to drill down into the paragraph so that I can add a Run to it.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp3
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.flowdoc.Document = new FlowDocument();
Run r = new Run("Hello ");
r.Background = new SolidColorBrush(Colors.Yellow);
r.FontSize = 14;
Paragraph p = new Paragraph(r);
flowdoc.Document.Blocks.Add(p);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Run r = new Run("World");
r.Background = new SolidColorBrush(Colors.LightCyan);
//Append run to existing run
//
}
}
}
<Window x:Class="WpfApp3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp3"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<FlowDocumentReader Grid.Column="0" x:Name="flowdoc"></FlowDocumentReader>
<Button Grid.Column="1" Content="append" Click="Button_Click"></Button>
</Grid>
</Window>
To get your Paragraph you may iterate the Blocks property of the document.
You can then easily add a new Run to the Block's Inlines collection.
private void Button_Click(object sender, RoutedEventArgs e)
{
Run r = new Run("World");
r.Background = new SolidColorBrush(Colors.LightCyan);
//Append run to existing run
var p = flowdoc.Document.Blocks.OfType<Paragraph>().First();
p.Inlines.Add(r);
}
Goal: Changing an image to another one when a red button is clicked.
But there is a problem when changing initial panda image to animation character image.
panda image is set up in the mainpage.xaml.
<Page
x:Class="App3.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App3"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button Height="100" Width="100" Click="Button_Click" Background="#FFEA2323"/>
<Image x:Name="image" Source="Images/panda1.png" Margin="436,170,418,174"/>
</Grid>
</Page>
And character image is set up when button is clicked
This is "mainpage.xaml.cs" code
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Shapes;
using Windows.UI;
using System.Windows;
// 빈 페이지 항목 템플릿에 대한 설명은 http://go.microsoft.com/fwlink/?LinkId=234238 에 나와 있습니다.
namespace App3
{
/// <summary>
/// 자체에서 사용하거나 프레임 내에서 탐색할 수 있는 빈 페이지입니다.
/// </summary>
///
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
image.Source = new BitmapImage(new Uri(#"C:\Users\hinon\OneDrive\Documents\2016-2\04. 놀이방\03. 키넥트 제스처 기반 게임 제작 환경 구성\03. 데이터베이스\01. 이미지\닥터슬럼프 아리.bmp", UriKind.Absolute));
//BitmapImage bitmapImage = new BitmapImage();
//bitmapImage.UriSource = new Uri(#"C:\Users\hinon\OneDrive\Documents\2016-2\04. 놀이방\03. 키넥트 제스처 기반 게임 제작 환경 구성\03. 데이터베이스\01. 이미지\닥터슬럼프 아리.bmp", UriKind.Absolute);
//image.Source = bitmapImage;
}
}
}
But it is not successful. If I click the button, initial panda image is dissapeared, and no image opend. just black. What I missed in this code?
Before click the red button
After click the red button
Ok so I am just practicing what is probably some very basic stuff with charts in wpf. I am fairly new to linq and wpf, so I apologize in advance if this is a silly question. I've got my LINQ to entity query returning all columns, I want to select two of the columns (Month (string), Points(int)) throw them into a dictionary, and then binding that to my chart..
Here is my XAML::
<Window x:Class="Chart.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:DV="clr-namespace:System.Windows.Controls.DataVisualization;assembly=System.Windows.Controls.DataVisualization.Toolkit"
xmlns:DVC="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DVC:Chart Name="testchart" Title="Statistics" Width="500" Height="300" LegendTitle="Stats">
<DVC:Chart.Series>
<DVC:BarSeries Title="Points"
IndependentValueBinding=""
DependentValueBinding="">
</DVC:BarSeries>
</DVC:Chart.Series>
</DVC:Chart>
</Grid>
And here is the code behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Controls.DataVisualization.Charting;
namespace Chart
{
public partial class MainWindow : Window
{
Dictionary<string, int> _data = new Dictionary<string, int>();
public MainWindow()
{
InitializeComponent();
using (CE ctx = new CE())
{
var query = (from r in ctx.ChartOnes
select r).ToDictionary(k => k.Month);
}
}
}
}
Thanks Dessus for your timely response! I will play around with your suggestions today. I did get some help from a co-worker yesterday and he was able to show me how to get it to work. Here is the edited code snippets:
<DVC:Chart Name="testchart" Title="Statistics" Width="500" Height="300" LegendTitle="Stats">
<DVC:Chart.Series>
<DVC:ColumnSeries Title="Points"
IndependentValueBinding="{Binding Path=Key}"
DependentValueBinding="{Binding Path=Value.Points}">
</DVC:ColumnSeries>
</DVC:Chart.Series>
</DVC:Chart>
and the code-behind:
private void LoadBarChartData()
{
CE ctx = new CE();
var query = (from r in ctx.ChartOnes
select new { Points = r.Points, Month = r.Month }).ToDictionary(k => k.Month);
((ColumnSeries)testchart.Series[0]).ItemsSource = query;
}
You should look up a model view view-model (MVVM) example of how to do databinding in WPF for chart controls (see: http://geekswithblogs.net/BillSontag/archive/2009/10/31/wpf-2-way-data-binding.aspx). The way you are doing your query in code behind will make it annoying (but can work) to get a reference to your control, but MVVM will make life easier once you get it working and get used to it. Your Linq query appears like it should output to a datatable as opposed to a dictionary.
Side Note: Any updates to the underlying LINQ collections will not trigger updates in your chart control. For that you would need something like: http://bindablelinq.codeplex.com/