Why does Firefox produce larger WebM video files compared with Chrome?

I and my team have been struggling lately to find an explanation why does Firefox produce larger WebM/VP8 video files compared with Chrome when using the MediaRecorder API in our project.

I and my team have been struggling lately to find an explanation why does Firefox produce larger WebM/VP8 video files compared with Chrome when using the MediaRecorder API in our project.

In short, we record a MediaStream from a HTMLCanvas via the captureStream method. In attempt to isolate everything from our app that might affect this, I developed a small dedicated test app which records a <canvas> and produces WebM files. I've been performing tests with the same footage, video duration, codec, A/V bit rate and frame rate. However, Firefox still ends up creating up to 4 times larger files compared with Chrome. I also tried using a different MediaStream source like the web camera but the results were similar.

Here is a fiddle which should demonstrate what I am talking about: https://jsfiddle.net/nzwasv8k/1/You can try recording 10-sec or 20-sec long videos on both FF and Chrome, and notice the difference between the file sizes. Note that I am using only 4 relatively simple frames/images in this demo. In real-world usage, like in our app where we record a video stream of a desktop, we reached the staggering x9 times difference.

I am not a video codec guru in any way but I believe that the browsers should follow the same specifications when implementing a certain technology; therefore, such a tremendous difference shouldn't occur, I guess. Considering my knowledge is limited, I cannot conclude whether this is a bug or something totally expected. This is why, I am addressing the question here since my research on the topic, so far, led to absolutely nothing. I'll be really glad, if someone can point what is the logical explanation behind it. Thanks in advance!

Building Chrome Extensions

Building Chrome Extensions

Wanna learn how to build Chrome extensions? Then this one is probably for you.


Developing and building Chrome extensions from scratch is as cool and amazing as it sounds. And it’s not complicated as it may seem at a first view. In this post, we will be covering all the essentials required to create your own Chrome extensions and build a simple Chrome extension.

And the best part of developing these extensions is that you don’t need to be an expert web developer. Fundamental knowledge of HTML, CSS, and JS is enough to build your own extensions. So, without consuming any more of your time with this intro, let’s get started.

Chrome Extensions are built with four main ingredients -

  • Manifest file
  • Content Script
  • Background Script
  • Popup

There are more things needed but these are the most crucial ones.


Manifest file

It’s a JSON file. Think of it as package.json. It tells us about the version, configurations, name and all the details related while building an extension.

Create a directory named MyExtension(you can name anything you feel like, but in this post, I will refer to it by MyExtension) and inside it create a manifest.json file.

manifest.json

There are a lot more things to be added in this file, which we will see in a few minutes. For a deeper view into manifest file, feel free to look here.


Content Script

A content script bothers itself with the current web page’s content. So, if you want to access Document Object Model(DOM) of the current page from your Chrome extension then this script is where you do that. Any DOM manipulation code goes here.

But we want our manifest file to know where are our content scripts. For that, we have to modify our manifest file.

content_scripts added

Here, the ‘matches’ key is an array which can contain the URLs for which the content script is to be run. In the above example, we want to run the content script for every website so we use <all_urls>. Whenever the page loads, the content script runs.

Let’s create a file content.js in the same directory and write some code in it.

console.log(document);

Once we do that we are ready to put our extension on Chrome.

  • Go to chrome://extensions/ .
  • Activate the developer mode.
  • Click on the ‘load unpacked’ button and add your MyExtension directory.

And that’s it, your extension will be activated on your browser and when you visit a page you can open your browser console and check that you have the respective site’s document object.

Since we now know how to use content scripts. Let’s do something cool with it.

Suppose, I wanna change the filter of all the images of every website I visit, It’s very easy. I have to only change the content script.

document.querySelectorAll('img').forEach((item)=>{

item.style.filter = "grayscale(100%)";

});

Or I wanna speed up the video I watch

document.querySelectorAll('video').forEach((item)=>{

item.playbackRate = 2.0;

});

Ah, it’s okay. But not very useful

True. We want our ‘extension users’ to be able to decide the playback rate so that they control the speed of the video according to their needs, and I’ll get back to it but before that let’s have a look at the background scripts.

Note: Whenever you make changes to any file of the MyExtension directory, you must refresh the extension OR you can download another extension(Extension reloader), this reloads all the unpacked extensions with a single click on a icon.

Background Script

Extensions are event-based programs used to modify or enhance the Chrome browsing experience. Events are browser triggers, such as navigating to a new page, removing a bookmark, or closing a tab. Extensions monitor these events in their background script, then react with specified instructions.

In layman terms, whenever the chrome browser is opened, the background scripts listens for events and responds to these events.

Again we have to make changes in the manifest file for the background scripts,

Now, let’s create a background.js file and write the following code:-

conosle.log('I am a background script');

Now if you refresh and check again there is no message in Chrome console because background script is not a part of the web page.

Go to chrome://extensions, and there exists a ‘i_nspect background page_’ link. Just click on that and there will be a different console with the respective message.


Browser action

browser_actions is used to put icons in the main Google Chrome toolbar, to the right of the address bar. So again the manifest file is to be modified:-

manifest.json

Now, this icon is clickable(fire browser actions) and our background script can listen to these actions.


Communication between the background and the content script

Chrome uses three APIs for the communication between the content and the background script.

Let’s make some changes in the background scripts.

background.js

When we click the extension’s icon the background scripts sends the message using sendMessage’ method. The callback function has a tab argument which is basically an object that has all the data for the current tab.

While the content script listens for the event and gets the data_._

content.js

Once the icon is clicked, the background script sends the message to the content script.

Now let’s build a chrome extension that allows the user to control the playback speed of the video.

The aim of the extension -> The user clicks on the icon, a popup is created with a slider from which the user can control the speed of the video.


Popup’s

When a user clicks on the extension icon, we want to generate a popup. This popup is an HTML file. But first, we have to update our manifest.json file

"browser_action":{

"default_icon":"icon.png",

"default_popup":"popup.html"

}

We create a popup.html file in the ‘MyExtension’ directory.

popup.html


Communication between popup & content script

We want to increase or decrease the playback speed of any video, based upon the user input. The best approach would be to take the input in the popup(using a slider) and then pass the slider value to modify the playback rate to the content script.

First, create a popup.js file and update the popup.html file by adding the script tag in it.

popup.html

While in the popup.js file, we’ll take the slider value and pass it to the content script.

popup.js

The content scripts get the slider value from the popup and modify the playback speed.

content.js

WOHOOO!! Created our first useful chrome extension. For the complete code, check here.

There is a lot more to when building chrome extensions and this post is just to get you started with it. If you want to take your skills to another level, just check out the docs.


Conclusion

In this article, we learned about some cool stuff related to Chrome Extensions. Hope you liked this article and learned something new, and if you did, clap your 💖 out and follow me for more content. Thanks for reading 🙏 Please feel free to comment and ask anything.


Learn more

Learn HTML5 & CSS3 From Scratch - Make Responsive Websites

Full Stack Web Development with Angular and Spring MVC

Creating Web Sites using Python and Flask

Full Stack Developers: Everything You Need to Know

How to Perform Web-Scraping using Node.js

Build a web scraper with Node

Develop a basic website with .NET CORE 3.0 and pure JavaScript

The Web Developer Bootcamp

Angular 7 (formerly Angular 2) - The Complete Guide

The Complete JavaScript Course 2019: Build Real Projects!

Modern React with Redux [2019 Update]

Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)

Build Responsive Real World Websites with HTML5 and CSS3

The Complete Web Developer Course 2.0

Originally published by Aayush Jaiswal at https://blog.bitsrc.io

Rspec and Chrome/headless flag

I've got headless Chrome and Chrome working for my Rspec tests. I want a flag to switch between the two so I can see the tests happen when I want and hide them when I don't. How can I implement something like:

I've got headless Chrome and Chrome working for my Rspec tests. I want a flag to switch between the two so I can see the tests happen when I want and hide them when I don't. How can I implement something like:

rspec --headless

Right now I just have this secret tied to a .env var:

Capybara.javascript_driver = Rails.application.secrets.headless ? :headless_chrome : :chrome


How to add Google sign-in to your Web app

How to add Google sign-in to your Web app

In this next part of the series, I’ll be walking you through an implementation of google sign-in with a simple react app and a bonus react-router example.

Up until now, we've seen 2 different hello world examples of how to add google sign-in on the front-end - using plain HTML and vanilla JS. It's been all nice and dandy for a hello world, but one thing thats been missing while I was figuring out google sign-in is what a working implementation looks like - especially in React.

*There is a react-google-login component that configures all of google sign-in behind a <GoogleLogin> tag. It's quite useful and I've used it in a few instances - my one complaint is that you can't get at the return value of the gapi.auth2.init() method. This post will show whats going on under the covers if you prefer not to use a library.

Creating a new react app with Google sign-in

First - create the app create-react-app google-auth-demo. The files we'll mainly be working with are App.js and index.html.

Add the google sign-in script tag to your public/index.html

<head>
  ...
  <script src="https://apis.google.com/js/api.js" async defer></script>
  ...
</head>
Add the login button

In App.js - add some state to keep track of when the user has signed in

contructor(props) {
    super(props)
    this.state = {
        isSignedIn: false,
    }
}

Add the button to the component

render() {
  return (
    <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
      &lt;p&gt;You are not signed in. Click here to sign in.&lt;/p&gt;
      &lt;button id="loginButton"&gt;Login with Google&lt;/button&gt;
    &lt;/header&gt;
  &lt;/div&gt;

)
}

Wait, how do I avoid showing this if the user is signed in? We can use the state to conditionally show it.

getContent() {
if (this.state.isSignedIn) {
return <p>hello user, you're signed in </p>
} else {
return (
<div>
<p>You are not signed in. Click here to sign in.</p>
<button id="loginButton">Login with Google</button>
</div>
)
}

}

render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Sample App.</h2>

    {this.getContent()}           
  &lt;/header&gt;
&lt;/div&gt;

);
}

  • Since conditionals are a little hard to write with inline JSX, I've pulled out the conditional block to another method to provide the component that we want.

At this point, you'll have a button that does nothing (the best type of button) and you'll see the "You are not signed in" message

Add sign-in

To finish setting up google sign-in, you'll want to initialize the library using gapi.auth2.init(). A good place to do that is inside of componentDidMount()callback.

componentDidMount() {
window.gapi.load('auth2', () => {
this.auth2 = gapi.auth2.init({
client_id: '260896681708-o8bddcaipuisksuvb5u805vokq0fg2hc.apps.googleusercontent.com',
})
})
}

To use the default styling, use the gapi.signin2.render method when initializing your component.

onSuccess() {
this.setState({
isSignedIn: true
})
}

componentDidMount() {
window.gapi.load('auth2', () => {
this.auth2 = gapi.auth2.init({
client_id: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
})

window.gapi.load('signin2', function() {
  // render a sign in button
  // using this method will show Signed In if the user is already signed in
  var opts = {
    width: 200,
    height: 50,
    onSuccess: this.onSuccess.bind(this),
  }
  gapi.signin2.render('loginButton', opts)
})

})
}

When using this method, the button will automatically show whether you're signed in, but the onSuccess callback won't actually run unless the user clicks it when it says "Sign In". Otherwise, you are logged in automatically. One way to hook into the end of that auto sign in process is by adding a callback to the promise returned by gapi.auth2.init:

window.gapi.load('auth2', () => {
this.auth2 = gapi.auth2.init({
client_id: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
})

this.auth2.then(() => {
this.setState({
isSignedIn: this.auth2.isSignedIn.get(),
});
});
})

Making a "protected" route

If you're using react-router and you want to add a "protected" route to your React app, you can hijack the render prop of a <Route>. You can do something like this:

authCheck(props, Component) {
return this.auth2.isSignedIn.get() ? <Component {...props} /> : <UnauthorizedPage/>

}

render() {
...
<Route path="/home" render={this.authCheck.bind(this, HomePage)}/>
...
}

By hooking into the render property on <Route>, you can dynamically define what component will load when you try to access that Route.

This is the strategy employed by the react-private-route project library to make it a little bit easier to write, definitely worth checking out.

Conclusion

If you're implementing google sign-in in a React app - check out my github repo intricatecloud/google-sign-in-demo to see all the code above in a working setup.

Throughout this 3-part series, we've covered going from a hello-world example of google sign-in, to using the javascript library to do some hacky things. Now, we've reviewed all the code you need to integrate with the Google Sign-In button.

Sometimes, tutorials like this can be hard to follow, and it just won't click unless you see it.

Thanks For Visiting, Keep Visiting

☞ React - The Complete Guide (incl Hooks, React Router, Redux)

☞ Modern React with Redux [2019 Update]

☞ The Complete React Developer Course (w/ Hooks and Redux)

☞ React JS Web Development - The Essentials Bootcamp

☞ React JS, Angular & Vue JS - Quickstart & Comparison

☞ The Complete React Js & Redux Course - Build Modern Web Apps

☞ React JS and Redux Bootcamp - Master React Web Development


Originally published on https://codeburst.io