Playing HTML video while taking a screenshot (drawHierarchy) - html

I'm having issues with thumbnailWebView.drawHierarchy(in:,afterScreenUpdates:) method and loading HTML code with a local video in it.
The issue comes when I capture the webview to get a tumbnail and then I click the video on the webview, the video start running (because the sound works) but the image keeps black. Also if I click the full screen option the video shows right.
The code is simple. Image capture:
UIGraphicsBeginImageContextWithOptions(self.thumbnailWebView.bounds.size, true, UIScreen.main.scale)
thumbnailWebView.drawHierarchy(in: thumbnailWebView.bounds, afterScreenUpdates: true)
let screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext()
Init WKWebView:
let conf = WKWebViewConfiguration()
self.thumbnailWebView = WKWebView(frame: CGRect(x: 0, y: 0, width: 768, height: 1024), configuration: conf)
thumbnailGeneratorView.addSubview(self.thumbnailWebView)
thumbnailControl = ThumbnailControl()
thumbnailControl.delegate = self
thumbnailWebView.uiDelegate = thumbnailControl
thumbnailWebView.navigationDelegate = thumbnailControl
Loading the HTML:
self.thumbnailWebView.loadFileURL(contentURL!, allowingReadAccessTo: contentURL!.deletingLastPathComponent())
If I comment the drawHierarchy line, the video shows right.
I have also tried to use view.layer.renderInContext(UIGraphicsGetCurrentContext()!) instead drawHierarchy but the screenshot obtained is white.

Related

iOS - Safari - images not rendering fully / cut off

We are loading images in a popup, via an Ajax request, and they intermittently only partially render.
I've basically removed any weird Javascript/nonsense other than the core flow - just a basic HTML image, and it is still happening - only on iOS.
Once you 'rotate' the device, the image renders correctly - so, it's not a weird div floating above or anything (I can select the image in iOS debugger mode when attached to a Mac)
Any help would be most appreciated.
Setting decoding="sync" on the img tag didn't help in my case where a lot of images are loaded simultaneously. Loading the image manually before did the trick though.
const imageLoader = new Image();
imageLoader.src = url;
imageLoader.decoding = 'sync';
imageLoader.onload = () => {
// allow drawing image
};
For anyone who stumbles across this and is working in a react environment
const [didLoadMainImage, setDidLoadMainImage] = useState(false);
useMemo(() => {
setDidLoadMainImage(false);
const imageLoader = new Image();
imageLoader.src = url;
imageLoader.decoding = 'sync';
imageLoader.onload = () => {
setDidLoadMainImage(true);
};
}, [url]);
return (
<div>
{didLoadMainImage ? (
<img src={url} />
) : null}
</div>
);
It seems this is an issue within the iOS image decoder - some kind of race condition.
This has been fixed by forcing the decoder to operate on the main thread, using:
<img decoding="sync" src="#Url" />
Hopefully this helps someone else!
In my case, the solution was to decrease the size of the images I was displaying. Our images were about 10x the size of the HTML element they were displayed in.
Apple's developer document states:

Adjusting the height of a wkwebview programmatically

This is my first question on Stack Overflow. I just started learning swift programming and got sucked into something.
I followed IAP tutorials on YouTube and successfully implemented AdMob banners and interstitial ads in my app. I was also able to turn off ads using the IAP. My question is:
I have a view in which I have two UI elements (WKWebViewand a GADBannerView). The WKWebView element covers 90% of the screen starting from x:0,y:0, whereas the GADBannerView element covers 10%. I turned off ads and hid the GADBannerView element using IAP.
Now I want to dynamically/programmatically adjust the WKWebView size to fill the entire screen, i.e 100%. In other words, I want the WKWebView element to extend over the hidden GADBannerView element.
This is because hiding the GADBannerView leaves a blank field which is not cool to the view and the WKWebView looks truncated.
Please note that neither of the views are subviews. Both are independent views added separately. I understand that I can initially make the web view fill entire screen, add the GADBannerView on top of it, and when I remove ads and hid the GADBannerView, the web view will fill screen. That is not what I want because some content of the web view can not be seen using this approach. If I have a button at the end of HTML page that loads on the web view, this button can not be clicked because it will always be behind the gad banner view even when scrolling reached the bottom. Yes, you can scroll and hold to see the button, but once you release it, it will go back down.
So as a recap, I have two separate views and want to hid one and extend the length of the other to cover the entire screen.
Please tell me how to achieve that.
thirdBannerView.isHidden = true //Hide the banner view
//then code below to increase the size of the web view to equal device //screen width and height i.e full screen.
func webViewDidFinishLoad(webView: WKWebView) {
//let screenBounds = UIScreen.main.bounds
// let heightq = screenBounds.height
//let widthq = screenBounds.width
//webView.frame.size.height = heightq
//webView.frame.size = webView.sizeThatFits(CGSize.zero)
//webView.frame = CGRectMake(0, 0, widthq, heightq);
webView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
}
This code is not effective at all as nothing changes. Please let me know how to achieve this.
This particular scenario looks promising for applying UIStackview. Add your two view ( WKWebview and GADBannerView). apply fixed height for the GADBannerview. Whenever necessary just hide the GADBannerview.
Sample code
class StackviewController : UIViewController {
let stackview: UIStackView = {
let view = UIStackView()
view.axis = .vertical
view.distribution = .fill
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
// Your WKWebview here
let sampleWKWebView: UIView = {
let view = UIView()
view.backgroundColor = .red
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
// Your GADBannerView here
let sampleGADBannerView: UIView = {
let view = UIView()
view.backgroundColor = .green
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
}
func setupViews() {
view.addSubview(stackview)
stackview.addArrangedSubview(sampleWKWebView)
stackview.addArrangedSubview(sampleGADBannerView)
NSLayoutConstraint.activate([
stackview.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0.0),
stackview.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0.0),
stackview.topAnchor.constraint(equalTo: view.topAnchor, constant: 0.0),
stackview.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0.0),
sampleGADBannerView.heightAnchor.constraint(equalToConstant: 100.0)
])
// Enable this line to hide the GADBannerView
// sampleGADBannerView.isHidden = true
}
}
Here is the output
I use two UIView to represent the WKWebView & GADBannerView. In the sample code uncomment the following to hide the bottom banner like green view.
sampleGADBannerView.isHidden = true

AIR Stagewebview not displaying youtube videos

I have trying to load youtube videos using stagewebview on AIR Desktop. (windows 10)
Code below:
var SWV:StageWebView = new StageWebView(true);
SWV.addEventListener(ErrorEvent.ERROR, swvErrorHandler);
var swvHeight:Number = stage.stageHeight - (75);
var swvWidth:Number = stage.stageWidth;
var swvYCoord:Number = 75;
SWV.stage = stage;
SWV.viewPort = new Rectangle(0, swvYCoord, swvWidth, swvHeight);
var vId:String = 'QowwaefoCec';
var urlToLoad:String = "http://www.youtube.com/embed/"+vId+"?rel=0&controls=1&showinfo=0&autoplay=0";
SWV.loadURL(urlToLoad);
Running the code gives a window with black background. Right clicking on it pops up the adobe flashplayer menu stating "Movie not loaded". Flash version is 25.0.0.148
If i use
urlToLoad="https://www.youtube.com/watch?v="+vId;
i get a malformed youtube page with majority of elements missing.
Tried with number of videos. result is always the same.
Can any one help please? I remember having tried out the above code a year or so back (when i was testing something else). It had definitely worked then. Cant fathom why it doesnot work now. Any help will be highly appreciated.
Please try the following:
var urlToLoad:String = "<!DOCTYPE HTML><html><body><iframe style=\"border: 0; width: 100%; height: 100%; padding:0px; margin:0px\" id=\"player\" type=\"text/html\" src=\"http://www.youtube.com/embed/" + vId + "?fs=0\" frameborder=\"0\"></iframe></body></html>";
SWV.loadString(urlToLoad, "text/html" );
Same problem. if you only want to play, try this:
browser.loadURL("https://www.youtube.com/v/hFupHx5G44s");

Video tag in electron

I'm trying to play videos (mp4) in an window loaded with Electron.
Weird thing : it works fine with only one video, with the others it shows a black screen. The only difference between all videos are their width and height (does that matter ?). Also, in a browser window all videos play just fine.
Here's the code that load windows in electron :
let mainWindow;
let playerWindow;
app.on('window-all-closed', function() {
if (process.platform != 'darwin') {
app.quit();
}
});
app.on('ready', function() {
mainWindow = new BrowserWindow({
title: 'MasterGameApp',
x: 910,
y: 500,
width: 800,
height: 460,
show: true,
resizable: false,
transparent: false
});
playerWindow = new BrowserWindow({
title: 'playerView',
x: 2250,
y: 50,
width: 1005,
height: 540,
show: true,
transparent: false,
fullscreen : true
});
mainWindow.loadURL('http://localhost:8889');
mainWindow.setMenuBarVisibility(false);
mainWindow.setAutoHideMenuBar(true);
playerWindow.loadUrl('http://localhost:8889/playerView');
playerWindow.setMenuBarVisibility(false);
playerWindow.setAutoHideMenuBar(true);
mainWindow.on('closed', function() {
playerWindow.close();
playerWindow = null;
mainWindow = null;
});
});
The videos url are simply given to a video tag inside a JS script like this $('#someDiv').append('<video id=\'backgroundvid\' autoplay><source src=\''+ content +'\' type=\'video/mp4\'></video>');
I don't understand why the browser can play every video but the electron window can't ... Thank's in advance
Ummm hey. I just saw the beginning of your URL property for the video tag is out of the inverted commas.
What you have:
$('#someDiv').append('<video id=\'backgroundvid\' autoplay><source src=\''+ content +'\' type=\'video/mp4\'></video>');
What you should have:
$('#someDiv').append('<video id=\'backgroundvid\' autoplay><source src="\''+ content +'\' type=\'video/mp4\'"></video>');
Have you tried changing that?
Stay lit; keep doing Electron. I am a great fan of it and can see its potential for future desktop applications. 👍👍👍
NOTE: Also, I am not sure what your CORS settings are or anything, but if it it trying to load videos locally, it may not let you.

Opening of links in new tab on Safari iPhone

I have a site that helps people create captions for their Instagram posts and evaluate hashtags. One of the features is as simple as making links of the hashtags to Instagram in order to see what types of images they contain. As I don't want the input they have just entered and evaluated to disappear I have made the links open in new tabs by using target="_blank" - this works perfectly on desktops but on iPhones nothing happens when you try to click on the hashtag links. I suspect that it might be some sort of protection by disabling target="_blank" links, but I am not sure. Everything is just simple html links. I have tried adding rel="noreferrer" but that didn't make any difference.
So if you have an explanation as to why it does not work that would helpful, but even more helpful would be a solution as to how I can obtain what I want on mobile devices as well, which is simply put: open a link in a new tab so that I don't lose input/state of page that I have just presented to the user.
Alternative solutions to the above issue are also very much appreciated.
Try this js code:
function openTab(url) {
// Create link in memory
var a = window.document.createElement("a");
a.target = '_blank';
a.href = url;
// Dispatch fake click
var e = window.document.createEvent("MouseEvents");
e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
a.dispatchEvent(e);
};
openTab('http://www.google.com');
you can find the original post here: http://whoknew.dk/programmatically-opening-a-new-tab-window-on-mobile-safari-55.htm
as dispatchEvent is deprecated, you could use:
function openTab(url) {
// Create link in memory
var a = window.document.createElement("a");
a.target = '_blank';
a.href = url;
//click
a.click();
};