Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Thursday, July 12, 2018

Syncing 2 videos playback

This little experiment explores how to sync playback of 2 online videos using the following logic:
  • Primary video used for audio (secondary video is muted)
  • Combined play / pause / progress / seek events
  • Offset threshold for synching by slowing down or speeding up the secondary video (default = 0.2 sec)
  • Offset threshold for synching by seeking the secondary video to the primary video time (default = 2 sec)
Happy - Pharrell Williams

Demo 2 - Click link to view
More and More - Captain Hollywood Project

Code is available on Github.


Thursday, November 16, 2017

Angular Scroll-to-top component

I've recently created a small component providing a scroll-to-top functionality for any Angular 4 app. You can add it to your project and style it according to your needs.
The component provides 2 API attributes:

scrollOffset:

The amount of page scroll offset (from the top) in pixels after witch the component is shown. Default value is 0.

scrollDuration:

The scroll animation duration (ms). Default value is 500.


Code is available on Github.

Demo:


Saturday, October 22, 2016

Angular 2 Checkbox Tree with Partial Selection

While working on a new Angular 2 project, we needed a checkbox tree that supports partial selection when only some children nodes are selected.
As we've been using the open source PrimeNG UI components library, it was simple enough to add check-boxes to the PrimeNG tree component using its build-in template support.
The more complicated task was to add the recursive logic required for setting parent selection on each node selection change.
Feel free to explore the demo, fork the source code on Github and use it for your own projects.





Saturday, October 8, 2016

Converting key / value text files to JSON

I'm currently working on the conversion of a huge Flex application to Angular 2. 
Flex uses text files containing key/value pairs for localization (i18n). 
In order to convert those to JSON, I've created a simple automating tool which allows dropping multiple text files and automatically converts the data to JSON.

I've made this tool available online with some useful properties to control the JSON output structure. Feel free to give it a try:

https://amirch1.github.io/blog/text2json/


Tuesday, May 31, 2016

Auto play HTML5 video on iPhone and iPAD

One of the holy grails of the online advertising industry, is the ability to automatically play video ads on mobile devices. 
Both Apple and Google prevent auto playback of video files on mobile devices running iOS and Android.
There are few solutions for this issue, most of them rely on rendering an image sequences to a Canvas element.

I've made some simple changes to my inline playback demo to enable auto playback of HTML5 videos on iOS. Sadly, this solution doesn't work on Android.
The solution is very simple. The video starts muted, as required by the online advertisement industry. Clicking the video enables audio as well.
On the iPhone, auto playback starts muted and inline. Clicking the video jumps to fullscreen playback with audio.
  • Demo: Open this link on your iPhone or iPAD to see the demo.
  • Code: View the full source code on Github
Code sample:

    var vid = document.getElementById("vid"); // get reference to the video object
    var intervalID = null;
    var time = 0;
    var speed = 15; // frames per seconds (fps). Change this value to balance quality against performances

    // wait for the onloadedmetadata event to get the video duration
    vid.onloadedmetadata = function() {
        var duration = vid.duration;
        intervalID = setInterval(function(){
            time++;
            if (time / speed <=  duration){
                vid.currentTime = time / speed;
            }else{
                clearInterval(intervalID);
                intervalID = null;
            }
        },1000 / speed);
    };

    // clicking the video stops inline playback and triggers native playback including audio. No need to seek.
    vid.addEventListener('click', function(){
        clearInterval(intervalID);
        intervalID = null;
        this.play();
    });



Explanation:

  1. Define the playback speed in FPS (frames per seconds)
  2. Wait for the onloadedmetadata event after which video currentTime property can be set
  3. Open a timer interval according to the defined speed and advance the video currentTime property on each interval
  4. Stop the interval when the video reaches its duration or clicked upon
  5. Upon video click execute the play() command on the video element
That's it!

Tuesday, February 23, 2016

Video spectrum analyzer using video frame colors

I've been playing with HTML5 audio API for a bit and came up with this video spectrum analyzer. 
It uses the Color Thief library to grab the frame colors at runtime and uses these colors to create the spectrum bar gradients.
The spectrum itself is drawn onto an HTML5 Canvas and updated using the requestAnimationFrame API. 
See the demo below and feel free to explore the code on Github and the official demo page.
This demo works best on Chrome and FireFox.

Sunday, January 31, 2016

Video filters - image adjustments using CSS3 filters

CSS3 filters can be used on native HTML5 video objects as well as on images. 
I've recently created a little widget that opens an image adjustments menu on top
of the playing video (thank you Muli Dayan for your help with this one!).

The widget allows video image manipulations using these CSS3 filters:

  • Brightness
  • Contrast
  • Greyscale
  • Saturation
  • Hue-rotate
  • Sepia
Chrome and Safari except CSS filers by defining the "webkitFilter" property.
FireFox requires definition of the "filter" property.
IE is not supported as it lacks support for CSS3 filters.

Feel free to play with the demo and download the source code from Github.


Monday, January 11, 2016

Inline video playback on iPhone - my solution

As iPhone users know, when viewing an online video on the iPhone, the video plays in full screen using the device native player.

This presents a major limitation for advertisers since video ads are not clickable and overlay ads cannot be displayed. 
Any custom user interaction during video playback is not supported which prevents interactive videos and games.

There are few approaches for a solution, and here is mine, which I hope you find helpful.

Demo (open on an iPhone): http://amirch1.github.io/VideoInline/
Github code under MIT license: https://github.com/amirch1/VideoInline

The solution:

  1. Create an Audio tag and give it the source of the Video tag. Audio tags support any video format (mp4, m3u8 HLS streams, live) and play inline.
  2. Hide the Video tag native controls using Shadow DOM CSS rules.
  3. Add custom Play / Pause button and a progress bar.
  4. Clicking the Play button triggers the Audio tag play() method. It also invokes the Video tag load() method which enables video seek operation.
  5. A timed interval is set to sync the Video tag currentTime property to the Audio tag currentTime property. The time interval actually defines the playback frame rate enabling balance between quality and performances. It also updates the progress bar.
  6. Seeking using the progress bar sets the Audio tag currentTime value. The Video tag updates accordingly by the timer refresh.
Thats it! 
Rather simple, provides real audio sync and supports all video formats including mp4, HLS and live streams.
Can be easily enhanced to support fullscreen playback without loosing interactivity and additional video controls.

Feel free to play with the code, submit pull requests and star the Github repository :)

Monday, January 4, 2016

Moving to Github Pages

I've just started using Github Pages.
My first project is an updated Video Color Sampler and I will add additional projects soon.



Wednesday, November 18, 2015

Calculating video frame average color and displaying its name

This little demo shows how to calculate the average color value of a video frame during playback. 
The color name is displayed as well as the color value. 
This can be useful when creating 508 accessible content, for example for color blinded people. 

I used the colorThief library for calculating the average color. 
Note that you can also calculate the frame average palette if you need to display more colors, 
however this results in slower performances.
After getting the color value, I use the "Name that color" library by Chirag Mehta to display the color name.

You can view the source code for this demo by right-clicking the demo and choosing "View Frame Source".


Saturday, August 29, 2015

My first commit to a Google open source project

I'm so proud that my first commit to a Google open source project was accepted and merged: https://github.com/googlecast/CastMediaPlayerStreamingDRM/pull/8
This commit enhances Google's example of a Chromecast custom receiver.
While the example demonstrates support for DRM, HLS and smooth streaming, it doesn't provide support for regular MP4 videos (progressive download).
After merging my pull request, I continue developing Kaltura custom Chromecast receiver for OTT, web and mobile.

Check out the example:




Wednesday, June 10, 2015

Using Adobe Illustrator to mark SVG elements for JavaScript targeting

Lately I've been working with complex SVG files, linking JavaScript interaction to various elements within the SVG markup. 
Its not an easy task to locate elements within the markup. Luckily, Adobe Illustrator comes to the rescue: 

  1. Within Illustrator, its very easy to use the direct selection tool to select the required element. It is automatically marked in the Layers window.
  2. Give the layer a name. This name later becomes the element ID in the SVG markup.
  3. Be carefull not to use the same names for multiple layers. While Illustrator doesn't really care, your HTML / JavaScript are much less forgiving...
  4. Use the "Save Aa" command to save your file as SVG.
  5. If you open your SVG in a text editor - you will notice that layer names are now element IDs within your SVG markup.



All you need to do now is select your element by its ID in order to assign a JavaScript interaction to it.
In this example, I wanted the sun in the picture to be clickable so I gave its layer the name "sun".
After exporting to SVG, all that remain is:


document.getElementById("sun").onclick = function(){
   alert("You clicked the sun!");
};

Give it a try - click the sun:


Monday, May 18, 2015

Angular JS: Manipulating SVG images

While playing around with SVG files, it seems only natural to bind them to an Angular JS controller and see what happens...


The Code:

HTML:
Controller:

Sunday, April 5, 2015

Bitbucket and Cloud9 - the prefect match!

For the first time, I've started a new development project without having any file setup on my computer.

I'm using Bitbucket as my source control repository.
Bitbucket is free for private repositories (as opposed to Github) and you can add up to 5 contributors for each project.

Cloud9 is a robust development environment within your browser. So wherever you are, if you have any type of Internet connected machine, you can work on your project.
The best part is that if you login into Cloud9 using your Bitbucket account, it will automatically import your project files.
It allows editing your project and automatically configures your SSH key so you can use GIT commands (with sudo rights!) from the build-in Ubuntu terminal.

So for me, Bitbucket and Cloud9 are a match made in heaven, or at least on a cloud...


Tuesday, October 21, 2014

SVG Coloring Page

I've been playing around with SVGs lately and was amazed at how easy it is to create a simple
coloring page that runs on almost any browser and device. No Canvas or HTML5 API.


Check it out:



The code is very simple:
I use jQuery to select all SVG elements that have a "fill" style and change the fill color upon click.

You can right-click and select "view frame source" to see the code - I'm sure you will find it simple to understand.

Tuesday, July 2, 2013

Web Fonts Dynamic Loading

In one of the applications I'm currently working on, there is a need to allow users to select  a font from a variety of Google web fonts.
Since I don't want to load all the fonts when the application loads, I've added some code to dynamically load only the selected font.
Below you can see it in action.
The code can be viewed in this jsFiddle.



Tuesday, June 25, 2013

Localization of HTML Elements

When creating a SPA (Single Page Application), many times we like it to be localization-ready,
meaning it can be easily translated to other languages. 
Without getting into the many aspects of localization (and sometimes internationalization), 
I would like to present a simple way to localize HTML elements using HTML5 "data-" attribute.

The idea is to add a key attribute to the HTML element that we want to localize. 
For example:

<span data-key="txt1"></span>

We then create a JSON file holding all the application text as key-value pairs. For example:

{
"txt1": "translated text 1",
"txt2": "translated text 2",
"txt3": "translated text 3"
}

For each language we create a separate JSON file.
When the application loads, we use jQuery to load and parse the JSON file.
Then we access each HTML element by its data-key and set its HTML to the corresponding value from the JSON data file:

  var appNS;
  (function (appNS) {
      appNS.initApp = function(){
      // load language file
      $.getJSON('en_us.json', function(data) {
        // json loaded - save to object
        appNS.Lang = data;
        for (var key in appNS.Lang)
          $('[data-key="'+key+'"]').html(appNS.Lang[key]);
        });
      }
  } (appNS = appNS || {}));
  
  $(document).ready(function () {
    appNS.initApp();
  });

In this example, I've also used a name space and a JavaScript module.
A working demo can be seen in this plnkr.


Tuesday, June 11, 2013

JavaScript Name Spaces and Modules

An important concept of modular JavaScript is name spaces usage. 
Since any variable declared in the code automatically becomes a global variable residing on the main window object, 
accidental overriding of variables could occur. Further more, code maintenance and modular components are hard to implement. 
The solution is using name spaces and JavaScript modules. Nested modules can also be easily created.
  • Name spaces are implemented using JavaScript objects.
  • Modules are achieved using JavaScript immediate functions. 
Here is a simple example:

var myAppNS;
(function (myAppNS) {
   myAppNS.prop = value;
   myAppNS.func = function() { 
      // do some stuff...
   };
} (myAppNS = myAppNS || {}));

Check out this jsfiddle to see an example.

For nested modules and nested name spaces - check out this plnkr.


About Me

My photo
I've been developing Internet and rich-media application for 15 years. In my work I emphasis usability and best user experience as well as sleek design. My main expertise are JavaScript, Flex and Flash.

Followers