2019년 9월 2일 월요일

has it

흔히 Rumor has it. 정도로만 접했는데 어느 영화에선가 The times has it, 혹은 다른 유명한 신문 이름이 붙어서 문장이 나오는 걸 보고 (아마 기자회견 장면이었던 것 같다) has it 쪽이 숙어라는 걸 깨달았다.

2019년 8월 3일 토요일

"기획서대로 만들었는데요?"의 어떤 버전

https://twitter.com/tkasasagi/status/1157512605054861312

종이의 도면이 벌레먹은 모습을 표현한 것이 목각에까지 남았다.

2019년 7월 30일 화요일

이메일 주소 기반 로그인을 사용하는 서비스에서 이메일 서비스 제공자의 서비스 중단에 대응하기

@yahoo.co.kr
@jr.naver.com
@dreamwiz.com 

* 영향을 받는 계정이 얼마나 많은가?
* 별도의 인증을 통해 이메일 주소를 바꾸도록 유도할 수 있는가?

2019년 7월 29일 월요일

미래는 이미 와 있다. 단지 널리 퍼져있지 않을 뿐이다 - 디스토피아도 그렇다.

https://twitter.com/alexhofford/status/1155514310308896768

시위에서 살아남기 위해 안전모와 마스크를 위시해 우산을 든 것까지는 발상이 좋다고 생각했다.
그런데 최루탄이 떨어진 자리에 바로 달려가 연무가 더 퍼지지 않게 물을 붓고, 그 처치가 끝날 때까지 라바콘을 덮어두는 게, 그리고 그 일사분란함이 마치 디스토피아 영화의 한 장면을 페이크 다큐 형식으로 찍어놓은 것 같았다.

GCE f1-micro

vscode remote-ssh를 붙여서 node 개발에 써볼까 했는데
자꾸 remote 접속이 떨어지고 ssh도 안 되는 증상이 생겨서 이리저리 찾아봤다.
원인은 메모리 부족으로 인한 시스템 과부하.
기본적으로 VM은 swap을 안 붙이는 구조이다 보니까 600메가 남짓한 RAM만으로 각종 js 환경을 띄우면 그대로 메모리가 넘쳐서 시스템이 얼어버리는 거였다.

파일 스왑을 붙여서 쓰는 방법도 있긴 한데, 성능이 워낙 애매하게 나와서 약간 포기.

2019년 7월 27일 토요일

network-manager, vpn, ubuntu, netplan

가상머신 안에서 항상 VPN을 연결하고 싶었다.

일단 network-manager-l2tp 패키지를 설치하고, 프로필은 실은 이미 설정된 다른 데가 있어서, 파일만 복사해다 /etc/Network/system-connections 안에 넣어줬다.

하지만 nmcli c u VPN_ID 만으로는 접속이 되지 않았다.
"Error: Connection activation failed: Could not find source connection." 이런 오류가 떴다.

이리저리 찾아보고 내린 결론은 nmcli가 VPN을 입힐 연결을 보유하지 않고 있기 때문인 거였다.
network-manager에 ethernet 장치를 추가해주면 되려나 싶어서 찾아봤는데 딱히 뭐가 없었다.

그러다가 netplan이라는 게 /etc/network/interfaces 파일 대신 쓰이게 됐다는 걸 알았다. 한참 전부터 써오던 설치본과는 달라서 당황했다.
/etc/netplan/*.yml 파일을 보면 (이미 이더넷이 구동되고 있을 테니) ethernets 장치를 활성화해주는 설정이 있을 거다. 거기에 "renderer: NetworkManager"라고 위임해주는 부분을 넣고 sudo netplan apply 라고 하면 설정 파일이 적용된다.

/etc/NetworkManager/NetworkManager.conf 파일의 ifupdown managed=true 설정으로 바꾸라는 건 적용이 되어있긴 한데 netplan 하위로 붙은 셈이니까 아마 영향이 없었을 것이다.

이제 nmcli device status 해보면 이더넷이 managed로 잡힌다.
nmcli c u VPN_ID 해봐도 바로는 안 되어서 재부팅을 한 번 했고, 잘 된다.

부팅 때 항상 VPN을 먹일 방법이 network-manager 안에는 없어보이고 /etc/rc.local 파일에 기록해서 처리했다. 우분투의 방법은 https://askubuntu.com/a/886631 를 참조해 systemctl 기능 안에서 해결했다.

2019년 6월 19일 수요일

Prisma

graphql을 언젠가 써보리라 생각했는데 마침 node로 DB를 읽을 일이 생겨서 prisma를 이리저리 해보았다.

결론은 기존 DB를 긁어와서 붙이는 데는 아직 난관이 있다는 것. mysql 지원도 불과 얼마 전에야 들어갔고, 그래서 introspect 직후의 결과물은 postgres에 적용되어야 할 옵션이 들어가서 수동으로 한번 고쳐줘야 써먹을 수 있다.

enum 필드는 enum 항목들이 대문자가 첫 글자여야 한다는 규칙이 붙어있어서 낭패였다. graphql 자체에는 달리 그런 명시가 없는 걸로 봐서 아마 prisma 구현체에서 오는 특성일 것 같은데, 나름 대원칙일 테니 바꾸자고 하기도 뭐하고.

2019년 5월 18일 토요일

HPE ProLiant MicroServer Gen10

하려던 건 대체로 해결이 됐는데 의외로 난관을 만났다.

iommu marvell 이라고 검색하면 잔뜩 나온다. 작더라도 그래픽 카드를 하나 꽂아서 VM에 붙여줄까 싶었는데, IOMMU 옵션을 켜면 디스크가 와장창 오류 나고 하나도 인식되지 않는다. KLDP에 CSM 켜보니 넘어가더라는 얘기가 그럴듯하게 보여서 바이오스 설정을 바꿔봤는데 효과가 없다.

혹시나 하는 마음에 GPT도 UEFI도 아니던 설치 상태를 어찌어찌 검색해가면서 GPT+UEFI 부팅이 되게 했다. 그 상태에서 다시 BIOS에서 CSM을 껐다 켰다 하면서 IOMMU를 시도해봤지만 IOMMU가 켜진 상태에서는 디스크 인식이 확실히 안 된다는 것만 확인했다.

그리고 순정 램 스펙과 똑같다고 적혀있는 램을 굳이 아마존에서까지 주문해서 꽂아줬다.

$ LANG=C sudo lshw -c memory -sanitize
  *-firmware                
       description: BIOS
       vendor: American Megatrends Inc.
       physical id: 0
       version: 5.12
       date: 06/05/2017
       size: 64KiB
       capacity: 8128KiB
       capabilities: pci upgrade shadowing cdboot bootselect socketedrom edd int13floppy1200 int13floppy720 int13floppy2880 int5printscreen int14serial int17printer acpi usb biosbootspecification uefi
  *-cache:0
       description: L1 cache
       physical id: 1b
       slot: L1 CACHE
       size: 320KiB
       capacity: 320KiB
       clock: 1GHz (1.0ns)
       capabilities: pipeline-burst internal write-back unified
       configuration: level=1
  *-cache:1
       description: L2 cache
       physical id: 1c
       slot: L2 CACHE
       size: 2MiB
       capacity: 2MiB
       clock: 1GHz (1.0ns)
       capabilities: pipeline-burst internal write-back unified
       configuration: level=2
  *-memory
       description: System Memory
       physical id: 4d
       slot: System board or motherboard
       size: 32GiB
       capabilities: ecc
       configuration: errordetection=multi-bit-ecc
     *-bank:0
          description: DIMM DDR4 Synchronous Unbuffered (Unregistered) 2400 MHz (0.4 ns)
          product: TEAMGROUP-ED4-2400
          physical id: 0
          serial: [REMOVED]
          slot: DIMM 1
          size: 16GiB
          width: 64 bits
          clock: 2400MHz (0.4ns)
     *-bank:1
          description: DIMM DDR4 Synchronous Unbuffered (Unregistered) 2400 MHz (0.4 ns)
          product: TEAMGROUP-ED4-2400
          physical id: 1
          serial: [REMOVED]
          slot: DIMM 2
          size: 16GiB
          width: 64 bits
          clock: 2400MHz (0.4ns)

2019년 3월 31일 일요일

내 네트웍이 안 되는 게 리눅스 커널 5.0.0 때문일 리 없어

며칠 전에 어떤 이유로 재부팅을 했다. 보통은 그냥 자고 깨고를 반복하는 데탑이다.

그 뒤로 자고 깨면 네트웍이 돌아오질 않는다. networking restart를 하면 아주 한참 지나서 랜 포트에 다시 불이 반짝반짝 들어오긴 한다.

랜 포트가 드디어 맛이 간 걸까, 공유기 문제일까 이 궁리 저 궁리를 해봤는데, 검색하다가 커널 문제는 어쩌구 하는 얘기가 보여서 혹시나 하고 uname -a을 해봤다. 5.0.0-7-generic. 그래, 5.0이 나왔댔지.


버전 낮춰서 다시 켜보니까 과연 잘 된다. 당분간은 4.19.0-13에 머물고 5.x 커널은 좀 나중에 써야지. e1000e 정도의 널리 쓰는 드라이버를 버전 올렸다고 뭐 크게 바꾸지도 않았을 것 같은데 왜 이렇게 되는지 모르겠다.

2019년 3월 27일 수요일

경주세계문화유산 학생 해설사 인증 과정

과제

4개의 문화재 지구 중 1개 지구 선택
지정문화재 중 1점을 선택하여 발표 (3분 이내)
나머지 문화재와 공통문화재 (경주)는 프리토킹 (4분 이내)

지구별 지정문화재

  • 1지구 (석굴암·불국사지구) - 석굴암, 불국사
  • 2지구 (월성지구) - 첨성대와 왕릉, 계림과 나정, 동궁과 월지
  • 3지구 (남산지구) - 남산, 포석정
  • 4지구 (한국 역사마을지구) -양동민속마을, 옥산서원

공통문화재

  • 경주

2019년 3월 26일 화요일

대중교통 거리 계산


일전에 먹부림 여행을 삼아 전라도에 갔다가 기차로 움직이는 경로를 따져본 적이 있는데 진짜 경부축만 멀쩡하고, 그 외에는 거의 대전을 거쳐가야만 했다.

그래서 전국 지도에서 각 지점을 대중교통 이용했을 때 시간거리로 나타내면 어떨까 궁금했다. 전국 팔도가 대전을 중심에 두고 불가사리처럼 짝짝 찢어지지 않을까 싶었는데, 조금 더 생각해보니 그 시간거리라는 건 두 지점이 정해졌을 때의 상대적인 값이니까 한 장의 평면지도에다 나타낼 수 없겠다는 생각이 들었다.

https://www.vw-lab.com/63

위 링크의 글을 읽고, 등시선도라고 한다는 걸 알았다. 여기서는 실시간으로 기준점을 옮겨가며 그려내는 걸 보여준다.

https://visgis.tistory.com/16

이렇게 그리는 게 가능하니까, 시각화의 차원을 높여서 일목요연하게 그리는 방법을 좀 더 고민해봐야겠다.

2019년 2월 10일 일요일

배달 거리 계산

http://woowabros.github.io/experience/2019/02/07/real-distance-finder.html?fbclid=IwAR3pL7lHY3JBAfPVD3b3n2B56WoItYoVKZ0Gq_zuN5yrMXH3Hqg-H3F0hBE

배달의민족 하위 기능으로 경로 계산을 어떻게 개선했는지를 설명하는 글을 보았다.
실제 이동 경로를 도로정보로 보정해서 처리하는 방식인데 배민이라면 이미 이동 정보가 많이 쌓였으니 충분히 가능한 일이고 앞으로도 개선의 여지가 있다. 시장 트렌드에 맞게 기계학습 같은 표제어를 붙여도 크게 틀린 말은 아니겠고.

일전에 다른 업체에 면접 갔을 때 내가 한껏 부풀에서 예상했던 작업이 저런 거였다. 실제로는 전혀 다른 부분을 기대했던 것 같고 내가 기대치에 미치지 못했는지 성사가 안 되기도 했고.
내가 당시 떠올렸던 건 도로 정보를 최대한 많이 수집해서 경사도나 공사 상황 같은 것도 포함하는 거였는데, 이동 경로를 가지고 시작한다면 이미 그런 것들은 반영이 된 상태일 테니 더 괜찮겠다 싶다.

2019년 1월 24일 목요일

DRM 동영상 스트리밍 서비스를 만들기 위한 모험

페이월 뒤에 일련의 동영상을 제공하는 서비스를 내가 만들 수 있는지 확인할 필요가 있었다. DRM도 포함해서.

그래서 몇 단계의 과정을 거쳐서 관련 정보를 찾아보았고, 알아가는 재미가 있었기에 브라우저에 열려있는 수많은 탭을 정리하며 여기에 그 과정을 남겨본다.


1단계 - 검색어 수집과 탐색

맨 처음이 뭐였는지는 기억나지 않는다. ffmpeg mp4 streaming 정도의 검색어로 시작했던 것 같다. ffmpeg가 이것저것 만능이라는 건 알고 있었는데, 실제로도 이런저런 검색결과가 나왔다.

2단계 - HLS라는 게 있다

검색결과에서 눈에 걸린 건 hls, rtmp 같은 용어였다.
https://www.keycdn.com/support/how-to-convert-mp4-to-hls 페이지에서는 hls 형태로 전환하는 명령이 나와 있다.
ffmpeg -i input.mp4 -profile:v baseline -level 3.0 -s 640x360 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls index.m3u8
 
적당한 동영상 파일을 index.mp4 파일명으로 맞추고 명령을 실행해보았다. index.m3u8 파일 하나와 indexNNN.ts 파일 272개가 생겼다.
m3u 확장자라면 재생목록인 걸 이미 알고 있고 m3u8 파일의 내용을 보아도 약간의 주석과 ts 파일들만 쭉 있었다. mpv index.m3u8 명령으로 실행해봐도 끊기는 마디 없이 하나의 긴 영상으로 뜬다.
이 정도면 파일들을 웹에서 접근할 수 있게 놔두면 그냥 재생이 될 것처럼 보인다.
 

3단계 - DRM 적용

다음으로는 ffmpeg create drm enabled content 정도의 검색어를 찾아보았다.
 
http://hlsbook.net/how-to-encrypt-hls-video-with-ffmpeg/ 페이지에는 hls를 만드는 ffmpeg 실행에 키 파일을 같이 넘기는 설명이 있다.
그럼 m3u8 파일에 키에 대한 언급이 들어가고, 해보진 않았지만 아마 결과물이 되는 파일도 키로 감싸져 있겠지.
 
https://stackoverflow.com/a/42721974/6629746 에서는 DRM이 보안 걸린 파일을 생성하는 것과, 서버와 사용자 간에 그 보안키를 공유하는 것으로 나뉜다고 전제하고 흔히 말하는 DRM이란 후자인 재생 쪽을 뜻한다고 설명한다.
https://shaka-player-demo.appspot.com/docs/api/tutorial-drm-config.html 페이지를 보라고 하는데 여기서는 재생기에 drm 옵션을 어떻게 주는지 설명하고 있다.
 
DRM 자체는 아직 정확히는 모르겠고 재생기를 붙이는 단계까지 가봐야 체감이 될 것 같다.
 

2.1 단계 - DASH라는 게 있다

DRM을 찾다 보니 걸려나오는 문서 중에 다른 것도 있었다.
 
https://www.axinom.com/creating-multi-drm-protected-videos-with-free-tools/ 페이지에서는 ffmpeg와 MP4Box라는 명령으로 dash라는 형식의 파일을 만들어낸다. 
MP4Box는 우분투에서 gpac 패키지가 제공하고 있어서 바로 설치하고 실행해봤다. 
생성되는 파일 중에 mpd 파일이 뭔지는 dash mpd 검색어로 검색해서 나온 https://stackoverflow.com/a/50060214/6629746 여기에 설명이 있다.
https://developer.mozilla.org/en-US/docs/Web/Apps/Fundamentals/Audio_and_video_delivery/Setting_up_adaptive_streaming_media_sources 페이지도 설명이 있는데 한눈에 들어오지 않는다.
  
dash hls라고 찾아보았다.
https://blog.wisen.co.kr/?p=2813 페이지는 CDN 업체의 홍보 페이지인데 DRM 적용된 인코딩 기능을 서비스로 제공하면서 그 일환으로 전반적인 구성을 설명한다. 특출하게 기술적인 내용을 담은 건 아니지만 길잡이로 삼을만했다. 
 
https://meetup.toast.com/posts/131 페이지에 한국어로 친절하게 정리가 되어 있었다. 
요약하면 DASH는 표준 규격, HLS는 애플 규격이었다.
 
모르는 말들이 나와서 caniuse.com에 물어봤다. 
  • https://caniuse.com/#search=hls - Edge와 웹킷 기반의 브라우저가 대체로 지원하는 걸로 보인다.
  • https://caniuse.com/#search=dash - Edge 말고 지원하는 브라우저가 없는 걸로 나온다. 
  • https://caniuse.com/#search=mse - DASH가 지원 브라우저가 거의 없는 건 실제로는 MSE를 통해 구현되기 때문이다.
  • https://caniuse.com/#search=eme - DRM을 처리하는 구현체의 이름. 당당하게 사파리가 빠져 있는데, https://github.com/Fyrd/caniuse/issues/4147 를 보면 실제로는 iOS 11.2부터 지원을 하는 걸로 되어 있다. 벌써 2018년 초반의 일인데 왜 caniuse 사이트에는 아직 미지원이라고 표시가 되어 있는지 모르겠다.

4단계 - 재생기

이쯤에서 내가 아는 DRM 동영상 서비스와 비교해봤다. 왓챠플레이.
왓챠플레이를 열고 브라우저 개발자 도구에서 웹페이지와 Network 탭을 뒤적거려보니 dash 기반이라는 것을 알 수 있었다.
마크업에 붙은 class 값을 보면 재생기는 DASH Everywhere인 걸로 보이는데 이게 그 사이에 이름이 바뀌었는지 검색해서 찾아간 공식 사이트처럼 보이는 곳에는 PRESTOplay라는 이름으로 나온다.
왓챠플레이를 쓰다보면 종종 알 수 없는 오류라면서 죽고 재생이 멈추는 경우가 있어서 왓챠에서 쓰는 건 택하고 싶지 않다.
 
https://blog.streamroot.io/how-to-choose-your-media-engine/ 페이지는 hls와 dash 형식마다 어떤 재생기를 쓸 수 있는지 표로 나열하고 있다.
iOS에서 DASH를 돌리는 것 말고는 다 방법이 있긴 한가보다. 
https://www.npmtrends.com/dash.js-vs-hls.js-vs-rx-player-vs-shaka-player-vs-videojs-contrib-hls 페이지를 보면 hls를 js로 구현하는 게 인기가 많다. 그렇다는 건 hls 포맷을 많이 쓴다는 걸까?
https://blog.videojs.com/dash-everywhere-ish-hack-project/ 페이지를 보면 iOS 때문에라도 HLS와 DASH를 모두 유지하도록 권하고 있다.
 
https://medium.com/@stepashka69/making-web-browser-play-streaming-video-mpeg-dash-smooth-streaming-hls-with-one-player-c5f4dd445b91 페이지에서는 아예 adapter를 하나 입혀서 구분없이 쓸 수 있게 하자는데 이게 실무에서 의미가 있을지 어떨지 모르겠다.
 

5단계 - 서버

이미 인코딩된 파일을 제공하는 것이니 파일을 제공하는 웹서버만 있으면 될 것 같다.

rtmp는 직접 인코딩을 실시간으로 할 수도 있는 것 같고 ffmpeg 인코딩을 받아서 내보내는 역할만 할 수도 있는 것 같다.
하지만 스트리밍을 대량으로 하려면 실시간 인코딩은 자원 소모가 심하고 지연도 발생할 것이니 선택할만한 방법이 아니다.

nginx를 그냥 쓰고 rtmp 플러그인을 추가하는 것도 보인다. https://hermantorjussen.no/how-to-livestream.html
apt search 명령으로 찾아본 우분투 패키지 중에는 crtmpserver라는 것도 있는데 자세히 찾아보진 않았다.

http://elelinux.blogspot.com/2015/11/dash-streaming-using-nginx.html 페이지에서는 nginx 설정에 rtmp 블럭을 두고 그 안에 dash 설정을 붙이는 방식이 나온다.
  

5.1단계 - 인증된 사용자에게만 서빙

paywall을 거쳐야 하기 때문에 접근을 제한할 방법이 필요하다. 

signed cookie, signed url이라는 용어를 초반 검색 어딘가에서 봤다. https://blog.embian.com/123 페이지였던 것 같다.
이건 탐색이 더 필요하다.
https://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html

encryption key rotation이라는 게 재생기 옵션에 대체로 있는 것 같으니 지원을 다들 하는 것 같다.

http://blog.leedoing.com/87 여기는 샘플로 할만한 코드가 있다.

6단계 - AWS 사용

AWS에도 스트리밍 기능은 있으니 AWS의 문서를 읽어보면 위에서 검토한 내용들을 맞게 이해했는지, AWS를 써먹을 수 있는지를 알 수 있다.

aws hls dash라고 검색하면 Elastic Transcoder나 Elemental MediaConverter가 나온다. AWS Elemental 시리즈가 신형으로 Elastic Transcoder를 대체하는 것 같다.
aws hls dash drm라고 하나 더 붙여도 특별히 달라지는 건 없지만 DRM 관련 정보를 더 직접적으로 찾을 수 있다.

https://medium.com/@whatauseless/aws-media-services-%EC%A0%95%EB%A6%AC-232484cbdbd6 페이지는 Elemental 시리즈의 대강을 설명하는데 비슷비슷하게 보여서 잘 모르겠다.

https://www.slideshare.net/awskorea/pooq-ott-case-for-live-vod-build-on-aws 페이지는 마침 AWS로 POOQ 서비스를 구축한 사례인데 대체로 알아들을 수 있다.
"서비스 운영" 장에서 "룰 베이스 미디어 파일명 사용으로 Manifest와 Media 의존성 제거" 부분은 감이 안 온다.
"서명된 쿠키 사용"은 JSON이 적혀 있는데 당장은 어떻게 사용되는지 다 이해가 되지는 않는다.

5.2단계 - 인증된 사용자의 유출을 추적

forensic watermark라는 용어가 이건 것 같다. cloudfront forensic watermark라고 찾아보면 이런저런 단어들이 나온다. ffmpeg forensic watermark는 자동완성으로도 뜨는데 검색결과는 신통치 않다.

AWS 관련으로 검색하던 중에 https://docs.pallycon.com/ko/multidrm/packaging/aws-elemental/ 페이지를 보았는데 메뉴에 포렌식 워터마킹이라는 항목이 있었다. 전자책 업체 등에서 사용자가 다운로드 받은 파일에 누구인지 구분하는 식별자를 붙여서 복제가 발생했을 때 누가 유출한 건지 밝힌다는 얘기가 이건가 싶었다.

https://docs.pallycon.com/ko/watermarking/mixing/ 페이지의 설명을 읽고서야 동작 방식이 이해가 되었다. 실시간으로 영상 인코딩을 하는 건 아니고, HLS나 DASH를 만들 때 각 세그먼트(파일 조각)을 아예 0,1 두 벌로 만들고, 둘 중에 어떤 걸 송출할지를 세션 정보에 따라 구분해서 결과적으로 완성된 스트림을 녹화한다면 어떤 세션 기준으로 조합된 것인지 알 수 있게 한다.

https://docs.pallycon.com/ko/watermarking/mixing/cloudfront-mixer/ 페이지를 더 읽어보면 조합 절차는 lambda edge로 처리하는데 이 부분은 부하가 걸리지 않으려나? https://www.tvbeurope.com/technology/nagras-watermarking-solution-integrated-into-amazon-cloudfront-cdn 페이지를 보면 NexGuard 제품도 같은 방식인 것 같다. 결국 실시간으로 처리하는 구간이 어딘가는 존재해야 하고 그게 CDN과 붙어있는 람다 엣지라는 거겠지.

https://docs.pallycon.com/ko/watermarking/detecting/ 페이지에서는 유출 의심이 생겼을 때 의뢰도 자기들한테 하라고 되어 있다. 직접 검출하려면 어떤 방법이 있을지 모르겠다.

7단계 - 웹 푸시

네이티브 앱이 당분간 없을 예정인데, 가급적 사용자의 주목을 끌고 싶은 마음은 있어서, web push를 같이 붙이고 싶다.
https://www.binpress.com/building-useful-notifications-html5-apis/ 페이지에는 푸시 말고도 유용한 방법을 더 안내하고 있다.

https://developer.mozilla.org/ko/docs/Apps/Progressive/Re-engageable_Notifications_Push 페이지에서는 service worker가 필요하다고 한다. 그렇다는 건 PWA 구현체가 되어야 한다는 거지.
https://github.com/GoogleChromeLabs/sample-media-pwa 이런 구현 샘플을 뜯어보면 이해가 되려나.

하지만 https://caniuse.com/#feat=push-api 표를 보면 지원 현황이 좋지 않다.
https://medium.com/@firt/progressive-web-apps-on-ios-are-here-d00430dee3a7 페이지를 보면 iOS와 안드로이드에서 지원이 꽤 다르기도 하다.

7.1단계 - TypeScript 도입?

가급적 ES6 내지는 TS 정도를 도입하고 싶은데, PWA나 service worker도 모르는 판국이라 엄두가 나지 않는다.

2019년 1월 7일 월요일

동영상을 배경화면으로 쓰기 위한 모험

리눅스 데스크탑 환경을 잘 쓰고 있는데 아쉬운 것 중에 하나는 배경화면에 iOS 환경처럼 동영상을 깔아둘 수 없다는 거다. 굳이 찾아보면 그런 게 된다고 하는 프로그램이 없진 않은데 내 환경이랑은 안 맞기도 하고, 어떻게 동작하는지 단박에 이해가 되지 않아서 내 환경에 들이고 싶은 마음도 안 든다.

X11 Root Window

가장 쉽게 떠올릴 수 있는 건 mplayer -rootwin 혹은 mpv -wid 0 옵션을 적용해 X11 root window에서 재생하는 건데, 이게 예전에는 자연스러운 동작이었지만 (윈도우 10라면 dwm.exe에 해당하는) compositor가 일상적으로 돌아가는 요즘은 (나는 compton을 쓴다) 재생이 시작되자마자 디스플레이 영역 전체를 덮으며 영상이 나오는 바람에 써먹을 수가 없었다.

게다가 여러 모니터를 쓰는 환경이라서 root window를 쓰기엔 어울리지 않았다. 꽤 넓은 이 해상도에 맞게 동영상을 그리면서 계단 현상이 안 생기려면 동영상 자체의 해상도가 어지간히 높아야 하기도 하고, 한 화면에만 동영상을 깔아두고 싶기도 했다.

일반 창 + 추가 속성

mpv 옵션을 한참 만지작거리다가, 굳이 root window일 필요가 없다는 걸 깨달았다. mpv --screen=0 옵션 정도로 0번 모니터에 창이 뜨면 일단 되는 거였다. (창 관리자에 따라서 안 될 수도 있다고 옵션 설명에 적혀있긴 하다)

거기에, 배경화면처럼 동작해야 하니 (흔히 쓰는 Always on top의 반대인) Always on bottom 속성이 먹혀야 하는데 mpv에 --ontop 옵션은 있어도 --onbottom에 해당하는 옵션은 없다. wmctrl -r gl.mpv -x -F -b toggle,below 명령을 쓰면 되는 것까지는 확인했다. 하지만 이게 다가 아니었다. mpv --no-border 옵션을 주거나, wmctrl로 fullscreen 속성을 주면, below 속성이 무시되고 포커스가 갔을 때 다른 창보다 위로 올라간다.

Openbox

그래서 다른 방식으로 해보았다. openbox는 rc.xml에 여러 설정을 먹여서 창을 세밀하게 관리할 수 있으니까, wmctrl으로 차례로 조정하던 속성을 아예 창 관리자 자체에서 한 번에 먹이면 뭔가 다르지 않을까 하는 생각이었다.

대충 아래처럼 rc.xml의 applications 요소 안에 넣어주면 되는데 (mpv --title 옵션을 썼다) 그래도 차도가 없었다. 터미널에 아예 above 속성을 줘봤지만 그래도 fullscreen 상태가 된 mpv 창이 더 위로 올라왔다. 아무래도 openbox가 지정하는 순서가 그런 것 같다.
    <application title="THIS_IS_IT">
      <layer>below</layer>
      <fullscreen>yes</fullscreen>
      <position force="yes">
        <monitor>1</monitor>
      </position>
      <focus>no</focus>
    </application>

혹은 fullscreen 대신 decor 속성을 끄는 방식으로 해봐도 똑같다. man의 설명에 따르면 mpv --no-border 옵션이 decor 속성에 대응한다는데 이건 wmctrl로는 해결이 안 된다.

몇 가지 조합을 해본 바로는, fullscreen 속성이든 decor 속성이든 상관없이 mpv가 해당 스크린 영역을 모두 차지해서 openbox가 뭘 더 그리거나 mpv 외의 남는 영역이 있지 않으면 below 속성은 무시된다. 혹시나 해서 gnome-mpv로도 실행해봤는데 똑같은 방식으로 동작한다. 이건 아마도 openbox가 전체 창을 다루는 방식 때문이지 않을까 싶은데 openbox를 대신할 창 관리자가 없어서 의심만 할 뿐이다.

결과

그렇다면 해결책은 이렇다.

openbox로는 mpv나 wmctrl로 적용이 안 되는 below 속성을 기본으로 주고, 창 크기를 1픽셀 줄여서 전체화면이 아니게 한다. (남은 1픽셀은 적당히 눈에 안 띄게 그 아래에 배경색을 깔아주면 된다)
창 크기가 1픽셀 줄어들었으므로 영상이 찌그러지지 않도록(=불필요한 이미지 재처리가 일어나지 않도록) 가로세로 비율이 창의 영향을 받지 않도록 하고, (이건 openbox에서 설정해도 무방한데) 전체화면이 아니며 창 테두리도 없으며 0번 화면에 표시한다. 소리는 끄고, mpv가 종료하면 다음 재생시에 끝난 부분부터 다시 재생하게 한다. 배경화면이므로 키보드나 마우스로 제어되지 않게 한다. 화면보호기는 평소처럼 작동하고 재생중이던 파일들은 무한 반복한다.
여기에 -vo vaapi 같이 적당한 가속 기능을 줘서 CPU나 GPU 어느 쪽을 쓸지 정해주면 된다. htop과 radeontop으로 확인했을 때 어느 쪽이든 부하가 걸리기는 한다.

rc.xml
    <application title="THIS_IS_IT">
      <layer>below</layer>
      <focus>no</focus>      <skip_pager>yes</skip_pager>
      <skip_taskbar>yes</skip_taskbar>
    </application>

mpv \
 --geometry=1919x1080 \
 --keepaspect-window=no --video-unscaled=yes \
 --fullscreen=no --no-border --screen=0 \
 -ao null --save-position-on-quit \
 --no-input-default-bindings --osc=no --window-dragging=no \
 --stop-screensaver=no --keep-open --loop-playlist