How to resume playing audio with MediaPlayer? - wpf

I have a WPF Caliburn.Micro application, and I use MediaPlayer class to play audio. I implemented Play, Stop, and Pause functionality, but I don't see a method for Resume (after Pause) in MediaPlayer. Could you please help me with this?
Here is some of my code:
public void Play()
{
try
{
var audio = Tpv.GetAudio(SelectedTpv.TpvId);
var file = Path.GetTempFileName().Replace(".tmp", ".wma");
File.WriteAllBytes(file, audio);
Player.Open(new Uri(file, UriKind.Absolute));
Player.Play();
IsPlaying = true;
}
catch (Exception ex)
{
MessageBox.Show(String.Format("Failed to play audio:\n{0}", ex.Message), "Failure",
MessageBoxButton.OK, MessageBoxImage.Error);
Console.WriteLine(ex.Message);
}
}
Thanks.

I'm pretty sure that Play is also supposed to handle resume functionality. According to the MSDN for System.Windows.Media.MediaPlayer the Play method is supposed to "Play media from the current Position". This means that when you are playing media from the beginning, the position is 0. If you pause, then the media will be paused at a certain position. Pressing play again should resume playback from the same position that you paused the media on.
Edit:
Based on the code update you provided, it looks like your issue is that you are loading the file each time you click play. This would cause any previous pause information to be erased, and would treat the file as being brand new each time. You should put some sort of check in there to say that if the file is not already loaded, then load it. Otherwise, your Play method should just call Player.Play() to resume.
I would also note that you would need to also call Player.Close when you switch the selected item. This would let the Play method know that it needs to load a different file.
public void Play()
{
try
{
// Check if the player already has a file loaded, otherwise load it.
if(Player.Source == null) {
var audio = Tpv.GetAudio(SelectedTpv.TpvId);
var file = Path.GetTempFileName().Replace(".tmp", ".wma");
File.WriteAllBytes(file, audio);
Player.Open(new Uri(file, UriKind.Absolute));
}
Player.Play();
IsPlaying = true;
}
catch (Exception ex)
{
MessageBox.Show(String.Format("Failed to play audio:\n{0}", ex.Message), "Failure",
MessageBoxButton.OK, MessageBoxImage.Error);
Console.WriteLine(ex.Message);
}
}

Related

System.Windows.Clipboard and MS Office applications

I am currently using System.Windows.Clipboard to: set some text, call SendInput with control+V, finally restoring the previous clipboard.
This works in most applications, though in Microsoft's Office applications the send input is causing the previous clipboard to be restored. I am assuming it is something to do with a delay in the SendInput method, so I added a wait before restoring and resolved the issue for most users, but Outlook for a user is still restoring the previous clipboard.
is there a better way of doing it than below?
try
{
//method that uses GetDataObject and stores it to be restored
_clipboard.Acquire();
try
{
_clipboard.SetText(ClipboardText);
//a wrapper for SendInput()
SendInputWrapper.SendKeyCombination(new KeyCode(VirtualKeyShort.Control),
new KeyCode(VirtualKeyShort.KeyV));
}
finally
{
//without this pause word and outlook would paste the original clipboard
await Task.Delay(TimeSpan.FromMilliseconds(200));
//wrapper method for Clipboard.SetDataObject() using the above stored
clipboard
_clipboard.Restore();
}
}
catch (Exception ex)
{
_log.Error("Error caught pasting text", ex);
}
Though it does not answer my direct question to Offices Clipboard buffer, the solution I have which now works is using Word.Interop:
var currentSelection = _word.Selection;
// Store the user's current Overtype selection
var userOvertype = _word.Options.Overtype;
// Make sure Overtype is turned off.
if (_word.Options.Overtype) _word.Options.Overtype = false;
// Test to see if selection is an insertion point.
if (currentSelection.Type == WdSelectionType.wdSelectionIP)
currentSelection.TypeText(text);
else if (currentSelection.Type == WdSelectionType.wdSelectionNormal)
{
// Move to start of selection.
if (_word.Options.ReplaceSelection)
{
object direction = WdCollapseDirection.wdCollapseStart;
currentSelection.Collapse(ref direction);
}
currentSelection.TypeText(text);
}
// Restore the user's Overtype selection
_word.Options.Overtype = userOvertype;

Disable Background Audio

I created the following code to play audio in my app. How can I stop the playback when the app is minimized? As of now, the audio will continue to play until the app is " destroyed "
backgroundMusicStream = Display.getInstance().getResourceAsStream(getClass(), "/backgroundMusic.mp3");
try {
backgroundMusic = MediaManager.createMedia(backgroundMusicStream, "audio/mp3", onComplete);
backgroundMusic.setVolume(35);
backgroundMusic.play();
} catch (Exception e) {
e.printStackTrace();
}
You can override the stop() method in the main class to stop "in progress" elements and invoke this code. You can debug this in the simulator using the Pause/Resume menu options.
BTW I would recommend using Log.e(exception) instead of printStackTrace().

Video having problems on my phone in Codename One

I have created an app for video demonstration using Codename one. I'm Facing some challenges when I'm running the app on my Google Android Phone as it does not allow a full screen view and also after the video is done playing, it does not go back or restart the video again. Another problem was that I had a button at the bottom at the borderlayout and each time I click the button, it corrupts the video and the video won't play anymore. These are codes used for my demonstration app Demonstration App 1, Demonstration App2 .
#Override
protected void postMain1(Form f) {
final MediaPlayer mp = findMpPresent();
try {
InputStream is = Display.getInstance().getResourceAsStream(getClass(), "/sbuda.mp4");
if (is != null) {
mp.setDataSource(is, "video/mp4", null);
} else {
}
} catch (IOException ex) {
ex.getMessage();
}
}
This is a bit unclear since I can't see the stop/start etc with a GUI builder application.
You can use native on-device controls for playback using setFullScreen. Notice that this works nicely on the device but has no equivalent on the simulator.
Once playback is finished the media no longer exists as your input stream has been depleted. You will need to create a new Media object. You can use the completion callback (the Runnable argument) to detect the end of the media.

Image always missing in the received message while sharing an image in Codename One

I am generating an image that is saved in FileSytemStorage.getAppHomePath() dir. I now need to share it via Email, SMS ... That's why I am using the following code (based on Codename One documentation) in my action method :
long time = new Date().getTime();
String fullOutputPath = FileSystemStorage.getInstance().getAppHomePath()
+ "Montage_" + Long.toString(time) + ".png";
// Save the image with the ImageIO class
try (OutputStream os = FileSystemStorage.getInstance().openOutputStream(fullOutputPath)){
ImageIO.getImageIO().save(montage.getMontageImage(), os, ImageIO.FORMAT_PNG, 1.0f);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Enable image sharing (outside the try/catch so that the outputstream in closed for sure)
if (FileSystemStorage.getInstance().exists(fullOutputPath)) {
Dialog.show("Saved", "Photo collage saved to " + fullOutputPath
+ " (file size = " + FileSystemStorage.getInstance().getLength(fullOutputPath) +" B)", "OK", null);
//Photo collage saved to file://home/Montage_14669... .png (file size = 50387B)
findValidateMontageShareButton3().setImageToShare(fullOutputPath, "image/png");
// Null pointer exception
So in that way I get a NPE and if I don't test if the file does exist there is no NPE but the image is still missing (both in the simulator and on the device).
The stack trace is as follows :
java.lang.NullPointerException
at userclasses.StateMachine.onPage3_ValidateMontageShareButton3Action(StateMachine.java:852)
at generated.StateMachineBase.handleComponentAction(StateMachineBase.java:757)
at com.codename1.ui.util.UIBuilder$FormListener.actionPerformed(UIBuilder.java:2835)
at com.codename1.ui.util.EventDispatcher.fireActionSync(EventDispatcher.java:459)
at com.codename1.ui.util.EventDispatcher.fireActionEvent(EventDispatcher.java:362)
at com.codename1.ui.Button.fireActionEvent(Button.java:411)
at com.codename1.ui.Button.released(Button.java:442)
at com.codename1.ui.Button.pointerReleased(Button.java:530)
at com.codename1.ui.Form.pointerReleased(Form.java:2627)
at com.codename1.ui.Form.pointerReleased(Form.java:2563)
at com.codename1.ui.Component.pointerReleased(Component.java:3158)
at com.codename1.ui.Display.handleEvent(Display.java:2025)
at com.codename1.ui.Display.edtLoopImpl(Display.java:1067)
at com.codename1.ui.Display.mainEDTLoop(Display.java:996)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)
It looks that the file my app is generating is not accesible to the sharing app. Do I have to add any extra permission as advised here for Android ?
Please note : I don't know if it is related to this problem but I cannot access to Codename One Settings menu from Eclipse anymore (maybe since upgrade to CN1 lib v 115)
Any help appreciated,
Cheers
So here is part of the answer which works in the simulator (ie the image appears in the fake email client => see image below).
So it appears that the share button cannot be set up in the action method (ie the method that is triggered when the user click on the share button). It has to be set up previously.
Consequently, in the beforeShow method my code reads as follows :`
FontImage.setMaterialIcon(findValidateMontageShareButton3(), FontImage.MATERIAL_CHECK_CIRCLE);
final long time = new Date().getTime();
// We generate the montage filename JPG otherwise it cannot be sent
montage.setMontageFullPath(FileSystemStorage.getInstance().getAppHomePath()
+ "Montage_" + Long.toString(time) + ".jpg");
// We assign the montage filename to the share button BEFORE we can click the button (otherwise the
// filename cannot be taken into account)
findValidateMontageShareButton3(f).setImageToShare(
montage.getMontageFullPath(), "image/jpeg");
Then in the onAction method related to the share button the code reads :
// Save the image with the ImageIO class
// We wait until the file is completely written to continue
Display.getInstance().invokeAndBlock(new Runnable() {
#Override
public void run() {
try (OutputStream os = FileSystemStorage.getInstance().openOutputStream(montage.getMontageFullPath())){
ImageIO.getImageIO().save(montage.getMontageImage(), os, ImageIO.FORMAT_JPEG, 1);
} catch (IOException e) {
Dialog.show("Erreur", "Impossible de sauvegarder le montage! Merci de vérifier l'espace disque disponible.", null, "OK" );
}
}
});
I tested it and it worked on the simulator but not on the device. Either with a png or a jpeg file, the file cannot be attached to the SMS or email (Android error message "abnormal file, can't attached file").
However if I do it a second time, then the file can be attached. So now the image is not missing but it cannot be attached (the first time) which is still embarrassing.

How to click on captured image using sikuli

I am new to Sikuli. I am Automating a web application that have option to upload a file.
When I click on upload button it opens a popup window.In that window I have to select a file. How I can do it using sikuli.
I am using linux operating system so I can't use AutoIT.
Below is my code which I am trying
public static void imageClick()
{
Screen s= new Screen();
try {
s.capture();
s.find("Desktop.png");
s.click("Desktop.png",0);
System.out.println("Desktop is selected");
} catch (FindFailed e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Desktop.png is a image file which I kept in my project. first I am searching it then clicking on it.
Anyone can help me how I can achieve this. Any help will be highly appreciated.
Finally I done in in below way
First import sikuli jar file to your project
Capture the Image where you want to click and save it to some location
for Ex. /home/dev/Desktop/abc.png
Screen s = new Screen(); //Created the Object of screen class
s.click("/home/dev/Desktop/abc.png");
public static void imageClick()
{
Screen s= new Screen();
Pattern DesktpIcon = new Pattern("Desktop.png");
s.click(DesktpIcon);
System.out.println("Desktop is Clicked.");
}

Resources