Troubleshooting HTML5 Video with JW Player

A Chrome extension to make it faster and easier

Ian Boynton
JW Player Engineering
7 min readNov 1, 2018

--

HTML5 video and video advertising are complicated technologies. They depend on a broad range of technical partners adhering to loosely standardized and often nascent systems that are constantly changing at the whim of the ever-changing tides of browser support and policies.

Our HTML5 player must work across the gamut of browsers to handle the range of content protection methods. It must also account for the different streaming types, file formats, and successfully digest and present content from a myriad of transcoding services. These services produce varying and sometimes incorrectly formatted renditions that cause players to stutter and break. Even more complexity is introduced when monetizing; ad networks, ad clients, and ad providers can produce a wide variety of XML VAST responses, which can lead to various errors.

This ecosystem is fragile and it can be hard to discern where and why things are not working. Fortunately, JW Player has a robust API, detailed analytics services, and an expressive event-system that, when used correctly, are a powerful set of tools. Without deep knowledge of these systems it can be overwhelming (as I know too well from my own first few weeks in the video space). Questions such as “where to look,” “what steps to take,” and “what questions to ask” are difficult to formulate and it’s often a challenge to locate exactly where in the chain something broke.

Reducing Complexity

Innovation is encouraged at JW Player and during our quarterly hackathon a few engineers and I started working on a product to increase accessibility by building an intuitive, comprehensive toolkit to debug and troubleshoot a JW Player instance. Our mission was to create a solution for any user to accomplish these goals:

  1. Make it easy to understand what a JW Player is doing on a page.
  2. Increase the accessibility of the players’ rich feature set.
  3. Reduce the barrier to consume the rich information it emits, and to distill our troubleshooting “best practices” into a simple click of a button.

Some months later, we are now proud to present JW Lens.

JW Lens

JW Lens is a browser extension built using a combination of JW Player event listeners and API methods, browser API’s, Vue.js, and VueX. JW Lens provides users a tab-based interface offering a distinct set of features and functionalities. At a high level, these tabs provide the following functionality:

  • Overview: Provides high-level context of the JW Player instance and its implementation on the page. This includes the current media file URL, the player’s buffer health, and other similar information.
Overview Tab
  • Config: Provides quick access to the configuration used to instantiate the player, and allows users to edit the configuration and re-initialize the player with a modified configuration.
View and Edit Player Configuration
  • Troubleshooting: Provides a roll-up of errors (player errors, media errors, and ad errors), as well as configuration validation, providing instant feedback on your configuration, including any misused, invalid, or missing configuration options.
  • Automated Ads Debugging: Refreshes the page a user-defined number of times, recording the ad performance for each “run”, and outputting a detailed report in a CSV file. This report includes summary information about the number of ad impressions and ad errors, as well as detailed information about each run, including specific ad error codes, and player bidding performance.
Troubleshooting Tab
  • Events: A filterable real-time feed of the events and accompanying data from the player.
JW Player Events Feed
  • Analytics: A filterable real-time feed of analytics pings dispatched by Google Analytics, along with the accompanying data.
  • QoE: Provides insight into the performance of the player and the page it lives on, providing player-specific metrics such as time to first frame, player setup time, and page “request to ready” measurements, as well as page-level metrics such as time to interactive, DOM load event, and DOM Content Loaded event.
Player and Page QoE
  • Report: Quickly capture all information required by the JW Player Support team to troubleshoot your issues. Designed to send alongside with a support ticket to facilitate a more seamless support experience.
Generate a report for JW Support
  • Open Test Page: Enables you to quickly test production environment players in sanitized, ‘barebones’ environment (without any external CSS or JavaScript). This can help isolate whether the issue you encountered is due to an issue on the production page or the player itself. Reports outputted by the Report can be uploaded using the Upload Report button, opening the same barebones page from the information contained in the report.

Technical Hurdles

During the development of JW Lens, we were faced with two overarching questions, how to make the interface as intuitive as possible and how to include more robust functionality within the context of an extension. Both of which our development team had little experience working in.

The first challenge we faced was determining whether we could use a JavaScript framework in the context of a browser extension. Not many of us had worked with Vue.js before, but with the project being born out of a hack week, we were excited to get some hands-on experience with the framework. In learning more about extension build packs, we turned to Webpack to quickly produce our first iteration, a ‘Hello World’ Vue application, giving us the foundation to start building out the functionality we were aiming to provide.

The next step was to start collecting the requisite data from the player instance on the page. In a typical debugging process, which relies heavily on the Chrome Developer Tools and test pages, this would simply involve setting up event listeners and calling any API methods as needed — standard JavaScript execution. In the context of a browser extension, however, this proved more difficult due to the nature of the browser’s architecture.

The two primary scripts that comprise an extension are the background and content scripts. These scripts live outside the context of the primary window, and do not share the namespace with the page. Because the namespaces were separate, we were unable to set up listeners for a player, or invoke the player’s API methods. We determined the workaround was to use script injection. While we could not set up listeners from the content or background scripts, we could access the document and append an additional script which would own these responsibilities. This script contained browser messaging which forwarded the relevant data back to the content script for sanitization, manipulation and rendering.

Browser extension architecture and API’s used

Leveraging browser storage in an efficient manner was another hurdle, underpinning the behavior for the automated ads reports and the ‘barebones page’ functionality (a new page opens with only the selected player and it’s configuration, and nothing else in the DOM). Instead of relying on the browser’s local storage, extensions are given access to two different storage options — storage.local and storage.sync; both offer differing amounts of storage capacity while accessible through the same asynchronous API. With these solutions, we were able to better control application state, save data between window refreshes, and pass the pertinent information we needed to re-compose the player and accompanying detail in a new tab.

As we began to test our POC’s on our customer’s production sites, we quickly came to realize that we would also need to be highly specific in our CSS rules. There are JW Players on hundreds of thousands of domains, and our goal was to have the same experience on every one of those pages. To facilitate this process, we adopted LESS, to take advantage of its nested structure, allowing us to apply fine-grain detail to our elements while avoiding conflicts with customers’ CSS — something that, due to the number of sites we work across, we continue to refine today.

What’s Next

JW Lens is currently in a closed-beta, but we are excited with the progress we have made, and with the value its already provided to internal users, as well as publishers. As we look to what’s next, we want to continue to gather feedback from early adopters, and further tailor the extension’s functionality to adhere to our mission of increasing accessibility. Our aim is to replace the mundane of video troubleshooting with the automated, and surface “hidden gems” of information that the player already captures, but may not be easily identifiable.

We are also excited about the medium of this application. From our research, browser extensions are not a widely relied upon method of delivering this type of functionality, especially in this industry. We hope that the work we have done with JW Lens can open up doors for the development of other tools to make our product the most easily accessible for any user.

If you are interested in joining the trial for Lens and providing feedback and helping us plot the future of the application, please let us know and we will reach out to you for additional information.

--

--