Android: MediaRecorder stop() freezes app - android-mediarecorder

I have an app to record screen videos. On some devices e.g. OnePlus 3t it works fine but on other devices like Samsung Galaxy s9 it freezes the whole app after stopping recording.
This is how I initialize the recorder:
private void initRecorder() {
mediaRecorder = new MediaRecorder();
mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmmss")
.format(new Date());
File storeDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Videos");
if (!storeDirectory.exists()) {
boolean success = storeDirectory.mkdirs();
if (!success) {
Log.e(TAG, "failed to create file storage directory.");
return;
}
}
mediaRecorder.setOutputFile(storeDirectory + "/video" + timeStamp + ".mp4");
mediaRecorder.setVideoSize(screenWidth, screenHeight);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setVideoFrameRate(16);
mediaRecorder.setVideoEncodingBitRate(3000000);
int rotation = getWindowManager().getDefaultDisplay().getRotation();
int orientation = ORIENTATIONS.get(rotation + 90);
mediaRecorder.setOrientationHint(orientation);
mediaRecorder.prepare();
}
The start method is invoked on a button click. When this button is clicked again it stops recording an the following method is called. This it where it freezes everything.
private void stopRecording() {
if (virtualDisplay == null) {
return;
}
virtualDisplay.release();
mediaRecorder.stop(); --> freeze
isRecording = false;
}
I have also tried to call the method stopRecording() in a separate thread. Then it does not freeze but the video is not saved. It seems to do heavy stuff in the stop() method that will never end. Any ideas?

Related

CefSharp Offscreen example as a dynamic library called by WinForm application

I wrote a shared library which consumes CefSharp.Offscreen to do the html retrieving work. It works fine when a Console Application calls it. But when a WinForm app connects it, after tcs.TrySetResult(true) is executed, it does not jump into await browser.GetSourceAsync() as what it did in Console App.
In WinForm App, it could be successful if any UI element is not created and not in the UI constructor, but if I create a UI element before calling the shared library, it fails always.
In another way, I force calling "var source = await browser.GetSourceAsync();" to get current html source, but it still does not response in WinForm connection.
[STAThread]
static void Main()
{
// I can put the init code here, but it does not help
//CefSimpleLib.CefTest.Initialize();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
TextBox tb = new TextBox(); // this blocks below call
CefSimpleLib.CefTest cf = new CefSimpleLib.CefTest();
Application.Run(new FormMain());
//CefSimpleLib.CefTest.UnInitialize();
}
namespace CefSimpleLib
{
public class CefTest
{
public CefTest()
{
// You need to replace this with your own call to Cef.Initialize();
// Default is to use an InMemory cache, set CachePath to persist cache
Cef.Initialize(new CefSettings { CachePath = "cache" });
MainAsync();
System.Threading.Thread.Sleep(1000 * 1000);
Cef.Shutdown();
}
private async void MainAsync()
{
var browserSettings = new BrowserSettings();
//Reduce rendering speed to one frame per second, tweak this to whatever suites you best
browserSettings.WindowlessFrameRate = 1;
using (var browser = new ChromiumWebBrowser("https://www.baidu.com", browserSettings))
{
await LoadPageAsync(browser);
var source = await browser.GetSourceAsync();
await Task.Delay(10);
}
}
public Task LoadPageAsync(IWebBrowser browser)
{
var tcs = new TaskCompletionSource<bool>();
EventHandler<LoadingStateChangedEventArgs> handler = null;
handler = (sender, args) =>
{
//Wait for while page to finish loading not just the first frame
if (!args.IsLoading)
{
browser.LoadingStateChanged -= handler;
tcs.TrySetResult(true);
}
};
browser.LoadingStateChanged += handler;
return tcs.Task;
}
}
}

directoryChooser.showDialog in javaFX app is freezing application after dierctory selection

DirectoryChooser directoryChooser = new DirectoryChooser();
File selectedDirectory = directoryChooser.showDialog(vbox_container.getScene().getWindow());
if (selectedDirectory == null) {
Logging.log(getClass(), LogType.INFO, "USER NOT SELECT OF DOWNLOAD DIRECTORY");
} else {
new UpdateDownload(version, selectedDirectory) {
#Override
public void onPreExecute() {
Label label = new Label("Downloading...");
label.getStyleClass().addAll("text-color-white");
vbox_container.getChildren().add(label);
}
}.execute();
}
After confirm of location in DirectoryChooser application is freezing for about 5 sec, than everything working fine... how to avoid described 5 secs freeze?

Codename One's MediaPlayer works in Simulator but on Android

I want to have a simple form that shows a video from a public URL. So I found out the MediaPlayer controller and I copied the example from the docs
final Form hi = new Form("MediaPlayer", new BorderLayout());
hi.setToolbar(new Toolbar());
Style s = UIManager.getInstance().getComponentStyle("Title");
FontImage icon =
FontImage.createMaterial(FontImage.MATERIAL_VIDEO_LIBRARY, s);
hi.getToolbar().addCommandToRightBar(new Command("", icon) {
#Override
public void actionPerformed(ActionEvent evt) {
Display.getInstance().openGallery((e) -> {
if(e != null && e.getSource() != null) {
String file = (String)e.getSource();
try {
Media video = MediaManager.createMedia(file, true);
hi.removeAll();
hi.add(BorderLayout.CENTER, new MediaPlayer(video));
hi.revalidate();
} catch(IOException err) {
Log.e(err);
}
}
}, Display.GALLERY_VIDEO);
}
});
hi.show();
It worked flawlessly in the simulator, the button appears and when I select a video file the component appears.
But when testing it on actual Android device, after I select the video nothing happens. I wonder if I missed some configuration. I am looking for the simplest possible way to run videos on Codename One for Android.
EDIT: It looks like the event listener in Display#openGallery is not being called.

Downloading a pdf file of larger size(like 30Mb) fails

I have used CN1CircleProgress library while downloading pdf files. It works great if the pdf file is small. But for larger pdf files eg 30 Mb, the circle fills to 100% 2-3 times very quickly and then again it starts to download to 20-30% & download stops. The file downloaded is currupted & cannot be opened in pdf viewer. I have checked it in iOS & android devices. In simulator it just downloads to certain percent, then it stops
downloadPdfButton.addActionListener((e) -> {
pdfUrlSelected = "http://roundtablenepal.org.np/uploadEpubs/57cbcc4e76258.pdf";
pdfFileNameIdSelected = currentPdfSelected.get("magazine_title");
filename = dir + sep;
filename = filename + pdfFileNameIdSelected + ".pdf";
FileSystemStorage.getInstance().mkdir(dir);
Slider downloadSlider = new Slider();
if (!FileSystemStorage.getInstance().exists(filename)) {
downloadPdfFromUrl(f, pdfUrlSelected, filename, true, downloadSlider, findCancelDownload(f));
}
});
private boolean downloadPdfFromUrl(Form f, String url, final String fileName, boolean storage, final Slider slider, Button cancel) {
crPdf = new ConnectionRequest();
crPdf.resume();
crPdf.setPost(false);
crPdf.setDuplicateSupported(true);
crPdf.setFailSilently(true);
crPdf.setUrl(url);
crPdf.setTimeout(15000);
crPdf.setDestinationFile(fileName);
final CircleFilledProgress p = new CircleFilledProgress();
p.setProgress(0);
f.add(BorderLayout.CENTER, p);
NetworkManager.getInstance().addProgressListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (evt instanceof NetworkEvent) {
NetworkEvent e = (NetworkEvent) evt;
if (e.getProgressPercentage() >= 0) {
slider.setText(e.getProgressPercentage() + "%");
slider.setProgress(e.getProgressPercentage());
}
}
}
});
slider.addDataChangedListener(new DataChangedListener() {
#Override
public void dataChanged(int type, int index) {
p.setProgress(index);
}
});
NetworkManager.getInstance().addToQueueAndWait(crPdf);
cancel.addActionListener((e) -> {
crPdf.kill();
});
return crPdf.getResponseCode() == 200;
}
I suggest opening the network monitor, I'm guessing you are getting a redirect which updates the progress then the redirect leads to an error page for some reason.

ImageViewer isnot working fine codenameone

I have a couple of questions regarding image viewer.
1)ImageViewer autoslides isnot working.The imageViewer works initially when the app is first started. But as soon as any other form is opened & then going back to the form containing imageViewer, the autoslide doesnt work.
Code for img viewer auto slide
placeholderForTable = (EncodedImage) theme.getImage("placeholderWithAnimate.png");
placeholderForTable = placeholderForTable.scaledEncoded(screenWidth, 30 + (screenWidth * 1 / 3));
BusinessForumImagesConnection bfic = new BusinessForumImagesConnection();
bfic.businessForumImagesConnectionMethod(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
DefaultListModel<Image> images;
if (bfic.response != null) {
for (Map<String, Object> entrySet : bfic.response) {
String imgUrl = (String) entrySet.get("imgUrl");
Image adImage = URLImage.createToStorage(placeholderForTable, imgUrl.substring(0, imgUrl.lastIndexOf(".")), + imgUrl, URLImage.RESIZE_SCALE);
adsSlideImagesArray.add(adImage);
}
}
ImageViewer imv = new ImageViewer();
Container adsContainer = BoxLayout.encloseY(imv);
if (adsSlideImagesArray != null) {
slideIndex = 0;
images = new DefaultListModel<>(adsSlideImagesArray);
imv.setImage(images.getItemAt(0));
imv.setImageList(images);
imv.setSwipePlaceholder(Image.createImage(100, 100));
Runnable r = new Runnable() {
public void run() {
if (slideIndex < images.getSize()) {
nextImage = (Image) images.getItemAt(slideIndex);
if (nextImage != null) {
imv.setImage(nextImage);
}
slideIndex++;
} else {
slideIndex = 0;
}
}
};
if (uITimer == null) {
uITimer = new UITimer(r);
}
if (uITimer != null) {
uITimer.schedule(5000, true, f); //5 seconds
}
}
});
2) Some random images are not always displayed in image viewer. It happens in both simulator & real devices. I have checked if the UrlImage is cached or not in storage. There are all the file saved but some of them are never displayed in image viewer.
Instead of image Viewer, i set the image icon in label and loop them. All the labels have their respective icons, but there is a problem in imageViewer. Code is same as above.
Make sure your timer fires and that no one canceled it.
Do you see the placeholder instead of the image? Details like that are essential.
Images that are deeper within the image viewer stack won't be pre-fetched. Notice that URLImage wasn't designed for the image viewer and is probably a bad idea for it as URLImage resizes the images. We recommend using a download method to get full sized images for the image viewer see this old post: https://www.codenameone.com/blog/image-viewer-from-the-web.html

Resources