HTML5 Video Tag

HTML5 HTML의 완전한 5번째 버전으로 월드 와이드 웹 (World Wide Web)의 핵심 마크업 언어이다. 2004년 7월 Web Hypertext Application Technology Working Group(WHATWG)에서 웹 애플리케이션 1.0이라는 이름으로 세부 명세 작업을 시작하였다.

HTML5는 HTML 4.01, XHTML 1.0, DOM 레벨 2 HTML에 대한 차기 표준 제안이다. 비디오, 오디오 등 다양한 부가기능과 최신 멀티미디어 콘텐츠를 액티브X 없이 브라우저에서 쉽게 볼 수 있게 하는 것을 목적으로 한다.
 W3C는 2014년 10월 28일 HTML5 표준안을 확정했다고 발표했다. - https://ko.wikipedia.org/wiki/HTML5

 

HTML4에서 5로 넘어오면서 audio, video, canvas라는 멀티미디어 관련 태그가 추가되었다.

W3C는 2004년 새로운 표준을 제안하였고, 단계적으로 HTML5를 지원하는 범위를 넓혀가던 2007년까지 HTML5에 대한 시선이 곱지만은 않았다.

이제는 레거시 시스템이 된 Silver Light와 Flash, Active X가 라이벌을 물리치고 평정한 시대였고, 브라우저가 HTML5를 랜더링하는 성능도 눈에 뛰게 부족했기 때문이었다.

 

하지만 HTML5가 있으면 모든 클라이언트 서비스(읽고, 쓰고, 보고, 듣는)를 지원할 수 있다는 희망이 생겨났고, 이를 증명하듯 수많은 웹앱이 태어났다. 스마트폰과 하드웨어의 발전이 계속되고 복잡한 웹생태계를 표준화하고자 하는 사람들의 열망이 모여 현재 Flash와 Silver Light, Actice X는 레거시를 넘어 웹생태계를 해치는 악의 축으로 밀려 나기 까지 했는데, 이러한 HTML5 내용 중 Video에 대해서 살펴보고자 한다.

 

Video element 는 Medeia element를 구현하고 있으며, 속성으로 src, poster, preload, autoplay, mediagroup, loop, muted, controls, width, height 속성을 가진다. DOM생성시 해당 옵션을 지정할 수 있으며 이름을 통해서 알 수 있듯이 플레이어가 지원해야할 기본적인 옵션들이다.

Video element의 DOM interface로는 width, height, videoWidth, videoHeight, poster가 있고, Media elemet에 current와 duration 같은 좀 더 상세한 interface가 있다.  상세내용은 아래에 첨부하였다.

 

W3C  Video 정의

Video Element

Content attributes

src
poster
preload
autoplay
mediagroup
loop
muted
controls
width
height

DOM interface
interface HTMLVideoElement : HTMLMediaElement {
           attribute unsigned long width;
           attribute unsigned long height;
  readonly attribute unsigned long videoWidth;
  readonly attribute unsigned long videoHeight;
           attribute DOMString poster;
};

Media elements (audio and video, in this specification) implement the following interface:

interface HTMLMediaElement : HTMLElement {

  // error state
  readonly attribute MediaError error;

  // network state
           attribute DOMString src;
  readonly attribute DOMString currentSrc;
  const unsigned short NETWORK_EMPTY = 0;
  const unsigned short NETWORK_IDLE = 1;
  const unsigned short NETWORK_LOADING = 2;
  const unsigned short NETWORK_NO_SOURCE = 3;
  readonly attribute unsigned short networkState;
           attribute DOMString preload;
  readonly attribute TimeRanges buffered;
  void load();
  DOMString canPlayType(in DOMString type);

  // ready state
  const unsigned short HAVE_NOTHING = 0;
  const unsigned short HAVE_METADATA = 1;
  const unsigned short HAVE_CURRENT_DATA = 2;
  const unsigned short HAVE_FUTURE_DATA = 3;
  const unsigned short HAVE_ENOUGH_DATA = 4;
  readonly attribute unsigned short readyState;
  readonly attribute boolean seeking;

  // playback state
           attribute double currentTime;
  readonly attribute double initialTime;
  readonly attribute double duration;
  readonly attribute Date startOffsetTime;
  readonly attribute boolean paused;
           attribute double defaultPlaybackRate;
           attribute double playbackRate;
  readonly attribute TimeRanges played;
  readonly attribute TimeRanges seekable;
  readonly attribute boolean ended;
           attribute boolean autoplay;
           attribute boolean loop;
  void play();
  void pause();

  // media controller
           attribute DOMString mediaGroup;
           attribute MediaController controller;

  // controls
           attribute boolean controls;
           attribute double volume;
           attribute boolean muted;
           attribute boolean defaultMuted;

  // tracks
  readonly attribute MultipleTrackList audioTracks;
  readonly attribute ExclusiveTrackList videoTracks;
  readonly attribute TextTrack[] textTracks;
  MutableTextTrack addTextTrack(in DOMString kind, in optional DOMString label, in optional DOMString language);
};

Youtube, Twitch, Pooq

실서비스 되고 있는 비디오 플레이어를 살펴보면, Html5 Video 태그로 플레이어 기본 기능을 구현한 것을 알 수 있다.

각종 버튼과, 광고노출과 같이 플레이어와 겹쳐서 보여지는 부분들은 DIV형태로 플레이어 위에 덧씌어져서 사용자에게 노출하고,

외부 Html요소를 이용하여 사용자로부터 전달되는 이벤트를 Video Eelement로 전달하는 방식으로 플레이어를 구현했다.

 

You Tube

 

Twitch

 

Pooq

 

Open Source

여러 종류의 Html5 Video Player 비교1, 비교2, 추천들이 있다.

다수의 Html5 Video Player 중에서 눈에 뛰는 두가지 오픈소스 플레이어를 소개한다.

 

두가지 플레이어 모두 플레이어 기본기능을 구현하고 있고, YouTube와 Vimeo완 연동이 가능하다.

또한 공통적으로 자막, 반응형, 스트리밍, 풀스크린, 다국어와 같은 사용자 편의기능을 포함하고있다.

 

Video.js의 Github Start는 16,549개다. Jquery가 45,000개 인것을 감안하면 엄청난 숫자이다.

사용자가 많은만큼 레퍼런스가 풍부하고, 대부분의 플러그인이 개발되어 있다.

커스터마이징이 필요없고, 하나의 솔루션처럼 Html5 Video Player가 필요하다면 가장 추천할만한 플레이어다.

 

Plyr의 Github Star는 9,469개다. 유명도에 비해 높은 Star 수를 보유하고 있으며,

경량화된 Html5 Video Player에 대한 개발자들의 요구를 반영하여 경량과, 커스터마이징에 초점을 맞추어 개발했다.

비교적 부족한 플러그인과 Owner가 육아에 돌입했다는 단점이 있지만 커스터마이징이 필수인 경우 가장 추천할만한 플레이어다. 

 

Video.js

  • 가장 사용자가 많은 Video Player Open Source (40만 사이트 이상)
  • HTML5와 Flash video까지 지원
  • 활발한 PR과 다수의 플러그인
  • js간 의존성이 높고, 파편화(좋은말로 모듈화) 됨
  • Apache License

Plyr

  • 경량, 커스터마이징에 초점을 맞춤
  • js 파일 하나, 10kb
  • 비교적 부족한 플러그인
  • Owner가 최근 육아에 전념함
  • MIT License

Solution

유료 솔루션 형태의 Html5 Video Player도 많이 있다.

유료형태의 솔루션은 HLS(스트리밍)지원과 광고 연동, 사용자 통계, DRM지원, Preview Thumbnail, 360 View, 고객지원과 같은 부가기능을 무기로 가격을 책정한다. 

하지만 Video.js 와 플러그인, hls.js와 같은 오픈소스들로 유료 기능들을 구현할 수 있기 때문에 플레이어만 판매하는 것을 넘어서 인코딩과 CDN, 그리고 스트리밍을 위한 서버를 함께 제공해주는 업체가 많다. 또는 플레이어를 무료로 풀고 고개지원에만 가격을 책정하는 업체도 있다.

자체적으로 스트리밍 서버와 CDN, 인코딩서버를 구축하기 힘든 경우 해당 업체를 사용하면 좋을것 같지만, 최근 AWS에서 워낙 친절한 솔루션을 내놓았기 때문에 개발자 관점에서 매력을 찾기는 어려울 것 같다.

OpenSource Issue (DRM, Streaming, Mobile, Ad)

오픈소스를 사용하여 Html5 Video Player를 구현할 때 어려운 점이 무엇일까 고민해보았다.

(유료 솔루션들이 해당 기능을 해결해주고 돈을 받는 것이기 때문에 유료 솔루션의 피처리스트들이 구현 시 어려운 점이었다.)

 

HLS Streaming : hls.js를 사용하면 된다.

DRM : hls.js를 사용하면 되지만, 스트리밍이 아닌경우 생각해봐야할 문제.

Mobile : 반응형 개발로 Web View 재생을 하면 되지만, 성능이 받쳐줄지는 미지수. 성능이슈라면 유료 솔루션도 어쩔수 없다.

Ad : 광고를 심는 시점과 고객 행동 데이터를 수집해야한다. 광고 노출기능은 Video.js에서 videojs-contrib-ads라는 플러그인 형태로 구현해 두었지만, 광고 전환율, 사용자당 클릭 퍼센트와 같은 통계데이터 수집은 따로 구현해야할 부분이다. 이 부분은 플레이어 자체의 기능이라기보다 서비스 플랫폼의 관점으로 바라봐야 할 것 같다.

결론

JavaScript개발시 어떤 프레임워크 또는 라이브러리는 사용할것인가? 라는 질문에 대답하기 위해 기술조사를 했다.

사용할 기술을 선택할 때는  언제나 트레이드 오프가 발생한다. 

따라서 개발하려고 하는 서비스와 팀의 규모를 고려해서 결정 하는 것이, 트렌드와 유행에따라 결정하는것보다 타당하다 생각한다.


기술조사를 마치고 느낀점은 Angular는 개발자의 자유도를 제한하는 대신, 우리가 마주할 수 있는 이슈에 대하여 기본적인 방법을 제시해고 있었고,

React는 스스로 라이브러리임을 밝히며 몸집을 최소화하며 개발자의 선택을 존중하고 있었다. 개발자의 자유도를 제한하지 않는면에서 잘나가는? 분야에서 조예가 깊은? 개발자는 React Family를 좋아하겠다는 생각을 여러번 했다. 실제로 기술조사를 하면서 React를 추천하는 곳에서 geek함과 개발자스러운 냄새를 맡을 수 있었다.


부족한 견해일지 모르지만 서버개발 프레임워크와 비교해보았을 때 Angular를 보면서 Spring같다는 생각을, React Family를 보면서 Node.js 같다는 생각을 했다. 또한 진정으로 POJO와 닮은 Vanilla JS의 간단한 페이지를 돌아보며 이것 또한 좋은 방법 같았다. Jquery 또한 여전히 사용성에서 1등을 고수하고 있었으며, 사용 추세가 전혀 줄어들지 않고 있었다.


다만 우리가 Spring을 사용하듯이, 팀단위로 일정한 수준 이상의 JavaScript 생산성과 품질을 유지하려면 Angular의 프레임 안에서 개발해나가는게 좋을 것 같다. 개발자에게 주어지는 자유도가 높을수록 성능은 높아질 수 있지만, 유지 보수와 협업의 관점에서의 성능은 어플리케이션의 규모가 커질수록 낮아질 것이다. 


만약 우리가 Front개발에 익숙하지 않은 팀이라면 Angular를, Front개발에 익숙한 팀이라면 React Family를 사용하는 것이 좋겠다.

소규모의 팀이거나 규모가 작은 서비스는 Front개발의 숙련도를 떠나 React Family를 이용하는것이 좋을 것 같다.

Framework

프레임워크란 무엇일까? 자바스크립트 프레임워크를 비교하기 전에 프레임워크에 대한 정의부터 분명히 해야겠다.

GoF의 디자인패턴 저자 랄프존슨은 "프레임워크란 소프트웨어의 구체적인 부분에 해당하는 설계와 구현을 재사용이 가능하게끔 일련의 협업화된 형태로 클래스를 제공하는 것" 라고 말한다. 혹자는 디자인 패턴 + 라이브러리 = 프레임워크라고 주장한다.


다양한 프레임워크가 존재하는 만큼 다양한 의미를 포함하고 있지만, 자바스크립트 프레임워크는 Inversion of control을 가능케하고 Modularity, Reusability, Extensibility 를 높이기 위한 목적을 가진 라이브러리 + 구조화 된 뼈대의 조합이라고 생각하면 좋을 것 같다. 우리가 흔히 사용하는 Jquery는 뼈대를 제공하지 않고 라이브러리만 제공하기때문에 프레임워크라고 부르지 않는다. Jquery를 사용해서 MVC 패턴을 입히면 그것은 프레임워크라 부를 수 있을 것이다.


최근 JavaScript가 사용되는 분야가 많아지고 인기가 높아지면서 오픈소스로 개발되는 자바스크립트 프레임워크들 또한 다양해지고 있다.

그 중에서 Angular 와 React를 비교해보고 이러한 상황을 비꼬는 듯한 용어인 Vanilla JS에 대하여 알아보자.

Angular

Angular는 MVC Framework로 최근 4.0버전을 출시했다. AngularJs는 1.x 버전을 지칭하고 Angular는 2.0 이후 버전을 지칭하는데, 1버전과 2버전은 패러다임의 변화가 있었고, 2버전 이후부터는 하위버전 호환을 유지하고있다. AngularJs에서 성능 문제의 주요원이었던 2 way data binding을 Angular에서는 빌트인으로 제공하지 않으며 서로 호환되지도 않음으로 분리해서 보아야 한다.


Angular는 구글 자체적으로 개발하던 AtScript를 사용하려 했으나, Microsoft와 협력하여 TypeScript를 채택했다.

한편에선 Facebook의 React와 달리 구글이 Angular를 사용하는 비중이 낮다는 점을 우려하고 있다. (YouTube를 새로 개편할 때 Polymer 사용)- 링크1, 링크2

React.js

UI 컴포넌트를 만들기 위한 라이브러리로, UI 컴포넌트만을 지원함으로 지원하는 범위가 작지만 다향한 조합으로 사용 할 수 있다.

React.js로 Angular의 directives를 구현하여 프레임워크를 구성할 수 있지만, 보통 Redux를 이용하여 프레임워크를 구축한다.

JavaScript와 TypeScript를 지원하지만 JSX라는 ECMAScript 친화적인 XML 문법을 사용할 것을 추천한다.

VanillaJS

VanillaJS는 자바스크립트 라이브러리와 프레임워크 홍수를 풍자하는 단어이다. 

Java에서 POJO와 비슷한 개념이라 볼 수 있다.


순수한 JavaScript만을 이용하여 구현한?(구현해야 할) 프레임워크다. 

별도의 라이브러리 없이 순수한 JavaScript만을 사용했기 때문에 가장 빠르고, 가벼운 장정이 있다.


http://vanilla-js.com/ 에서 사용하고 싶은 컴포넌트를 선택 후 다운받아 소스를 열어보면 그 의미를 더욱 잘 알 수 있다.



Angular VS React.js ? (2016 데뷰 정리 - 영상 , 발표자료)

위에서 설명했듯이 Angular는 프레임워크고 React.js는 라이브러리다. 

둘을 1:1로 비교하는것은 무리가 있고 Angular VS React Family(React.js + Redux + React router + Babel) 정도로 비교해야할 것이다.

2016년 데뷰발표자료에 사견을 더해 둘을 비교해 봤다.

1. 성능

https://github.com/CoderK/js-framework-benchmark 로 성능 평가 해본 결과 

 

 Angular

React 

Vanilla 

 상대 시간

 2.12

2.00 

 1.00

 메모리 사용량

 2.67

1.79 

 1.00

의미있는 속도차이는 없었음. 엔터프라이즈급 서비스 개발을 위해서 생산성에 좀 더 초점을 두어야 할것 같다.

학습 비용은 비슷하다고 생각함.

2. 언어 생산성

최근 Angular CLI 까지 나오면서 개발 환경과 학습 비용은 Angular가 낮다고 생각한다. 

또한, Angular가 사용되는 곳이 많아지면서 (웹앱, 앱, 데으크탑 앱) 사용성도 증가되고 있다. 


 Angular

 React

  •  구글은 웹표준을 철저히 지키는 회사. 
  •  새로운 언어를 배운다는 개념보다 Next Es 라고 생각하자
  •  구글이 만든게 표준이 아니면 표준을 추가하려고한다...?!
  •  TypeScript는 지나친 비용을 야기한다. 
  •  타입 체커 라이브러리인 FLOW면 충분하다.
  •  언어 생산성 측면에서 JavaScript 언어의 한계가 존재 했고 TypeScript가 탄생했다. 
  •  Angular 와 React 모두 TypeScript를 사용할 수 있지만, React는 타입을 지정해 주는 체커형태 라이브러리인 FLOW를 더 많이 사용하는 편

3. 컴포넌트

 Angular

 React

  • Angular는 HTML 과 JS CSS 를 잘 분리했고 CSS 캡슐화를 내부적으로 지원해서 높은 이식성과 재사용성을 보장한다.
  • JSX를 쓰면 마크업이 JS안으로 들어가는 형태. 코드를 실행하기 전까지 마크업 미리보기가 안된다. 또한 자바스크립트를 모르는 마크업 개발자와 협업할 경우 협업 자체가 매우 어렵다.
  • Angular는 표준 HTML에 디렉티브를 확장해나가는 개념이라 기존 HTML 문법을 그대로 사용할 수 있다.(React는 className, defaultValue 같은 문법 사용)
  • React역시 Webpack를 사용하면 CSS 캡슐화를 지원할 수 있지만 네이티브로 지원하지 않은 것은 조금 아쉬운 부분인건 사실.
  • 협업이 어려운점은 동의한다. 하지만 Angular도 Html에 논리코드(디렉티브)를 끼워넣어야 함으로 구조 안에 행위를 집어 넣는 순간 순수하지 못하다.
  • 사실 구조와 기능을 분리할 수 없다. 그래서 통합하는 것을 목적으로 했고, JSX 는 기존 javascript에서 DOM을 생성하던 것의 단점을 보안하고 가독성을 높인 결과물이다.
  •  컴포넌트 = HTML + JS + CSS
  •  CSS분리에 대해서는 동의하지만 JSX의 존재에 대하여선 대립 

4. 데이터 동기화

 Angular

 React

  • Angular의 경우 양방향 바인딩으로 성능이슈가 있었지만 Angular2와 React는 상당히 닮아있고 성능부분에서도 비슷해짐.
  • Angular는 React의 Virtual DOM을 보고? 체인지 디렉터라는 것을 만들었다. 마찬가지로 모델이 바뀌면 트리구조의 DOM을 훑으면서 달라진 부분만 다시 그린다.
  • Angular는 조금 더 나아가서 Zone(실행영역)이란 것을 이용해서 DOM 변경시 setState, setValue를 개발자가 명시하지 않아도 자동으로 모델을 변경시켜준다. (React 는 DOM -> Model 은 명시해줘야함)
  • React는 Virtual DOM을 이용하여 모델이 바뀌면 새로운 Virtual DOM을 그리고 기존 Virtual DOM 과 비교해서 Diff 된 부분만 새로 그려준다.
  • 뷰와 모델의 분리 후 데이터 동기화 문제 등장. 
  • Angular의 경우 양반향 바인딩으로 성능 이슈가 있었지만, Angular2로 넘어오면서 개선된 상태

5. 비동기 처리

 Angular 

 React 

  • 비동기 처리를 위해 RxJS를 품었다. ZONE을 이용한 DOM -> MODEL 로 데이터 전송처럼 Angular 자체적으로 RxJS는 잘 품었다.
  • Javascript가 가진 다른 대안도 많은 와중에 왜 RxJS를 품은 것인지는 더 지켜봐야할 일
  •  React는 라이브러리인 만큼 Angular보다 자유롭게 비동기 라이브러리를 쓸 수 있다.
  • 페이스북은 리엑트를 라이브러리로 지원하기 때문에 RxJS를 포함하려고 하는 움직임은 없지만 커뮤니티에서 활발히 진행 중. 
  • 또한 React와 함께 쓰는 Redux와 RxJS 는 궁합이 좋고 NetFilx에서 사용한 예가 있다.
  • Angular가 RxJS를 플레임워크로 품은것은 관심가지고 볼 사항이다.




Node.js의 탄생과 JavaScript라는 언어의 범용성이 커짐에 따라 JavaScript의 테스트 환경은 점점 더 중요해졌다.

JavaScript가 서버언어로 사용되면서 JavaScript 테스트는 e2e 테스트 뿐만아니라 BDD 또는 TDD가 가능한 유닛 테스트가 필요했고,

기존 테스트 환경은 발전했고, 새로운 테스트 프레임워크들이 탄생했다.

 

여러종류의 테스트 프레임워크 중 Mocha, Jasmine, QUnit을 비교해보자.

결론

테스트는 개발을 돕기위한 도구일 뿐 목적이 아님으로 개발 환경에 맞고 사용하기 편한 툴을 선택하면 된다.
테스트 속도 차이는 미비하고, 대부분의 툴들이 비동기 테스트를 지원함으로 테스트 툴간 성능비교는 무의미 한 것 같다.

자바스크립트 프레임워크를 사용하지 않고 Jquery만 사용한다면 Qunit으로 간단하게 테스트 환경을 구축하면 되고
Angular와 같은 자바스크립트 프레임워크를 사용한다면 Mocha와 Jasmine중 선택하면 될 것이다.

TDD를 생각한다면 DOM 이 필요 없는 Jasmine을 확장성 높은 테스트 환경을 생각한다면 Mocha를 선택하면 좋겠다.
나는 테스트 기능에만 충실하고 별도의 Dependency 설정이 필요없어 사용하기 쉬운 Jasmine을 선택하고 싶다.

테스트 비교

 

 Mocha 

 Jasmine

 Qunit 

 버전

 3.4.0

 2.6.1

 2.3.2

 인기

 중간 

 높음 

 낮음 

 assertion 라이브러리

 chai 라는 외부 라이브러리 사용

 내장

 내장

 러너

 Karma 가능 

 Karma 가능 (Python, Ruby)  Karma 가능 

 난이도

 보통 (3rd party library 필요, 유연함)

 쉬움   가장 쉬움 

 커뮤니티

12.3K github Stars, 4.45K stack over flow 

 12.4K github Stars, 8.01K stack over flow

 3.63K github Stars, 1K stack over flow

 특징

 Simple, flexible, fun javascript test framework for node.js & the browser  DOM-less simple JavaScript testing framework

 A JavaScript Unit Testing framewor

테스트 문법

 Mocha 

 

var assert = require('assert');
describe('Array', function() {
describe('#indexOf()', function() {
it('should return -1 when the value is not present', function() {
assert.equal(-1, [1,2,3].indexOf(4));
});
});
});
 Jasmine
 

describe("A suite is just a function", function() {
var a;
it("and so is a spec", function() {
a = true;
expect(a).toBe(true);
});
});

 Qunit 
 


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>QUnit Example</title>
<link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.3.2.css">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="https://code.jquery.com/qunit/qunit-2.3.2.js"></script>
<script src="tests.js"></script>
</body>
</html>

 

QUnit.test( "hello test", function( assert ) {
assert.ok( 1 == "1", "Passed!" );
});

사람들이 좋아하는 이유(출처 https://stackshare.io/stackups/jasmine-vs-mocha-vs-qunit)

 Mocha

 Jasmine 

 Qunit 

 105 오픈소스

 50 TDD 로 사용할 수 있음

 5 단순함

 77 단순함

 39 오픈소스

 3 오픈소스

 62 Promise 지원

 14 RSpec 표준

 3 세팅하기 쉬움

 32 유연함  11 DOM조차 필요없는 독립성

 2 Promise 지원

 18 사용하기 쉬움

 10 훌류한 커뮤니티

 
 7 브라우저와 서버 테스트  5 세팅하기 쉬움  

 2 다른 좋은 대안이 없음

 3 단숨함  
 

 2 Pivotal-Labs에서 개발함

 

Stackshare 특징비교 (https://stackshare.io/stackups/jasmine-vs-mocha-vs-qunit)

구글 트렌드
























+ Recent posts