728x90
반응형

크롬에서 fetch에 헤더를 설정하고 요청하는 경우 CORS 오류로 실패하는 경우가 발생했다.

 

처음엔 크롬 업데이트를 하고 난 이후 뭔가 변경돼 발생한 문제로 생각했다.

 

헤더 설정을 하지 않고 요청해보니 처음엔 307 Internal Redirect 한 다음 데이터를 가져왔다.

 

그래서 307이 뭔지 찾아보니 한 번이라도 HTTPS로 요청한 적이 있는 경우

 

해당 주소를 HTTP로 요청하면 발생하는 상태값이었다.

 

빠르게 해결하는 방법은 chrome://net-internals/#hsts > Delete domain security policies 에서

 

해당 주소를 입력하고 제거하거나 HTTPS로 요청하면 된다.

반응형

'JS' 카테고리의 다른 글

[JS] video.js 자동 재생이 안될 때 해결 방법  (0) 2020.09.24
[JS] Electron으로 앱만들기  (0) 2020.08.13
[JS] PWA 만들기  (0) 2020.02.20
[JS] ejs SyntaxError  (0) 2020.01.25
[JS] RegExp 재사용할 때 문제 해결  (0) 2020.01.25
728x90
반응형

video.js를 이용하여 HSL 동영상을 재생하는데 자동 재생이 안되는 경우가 있었다.

 

그래서 원인을 찾아보기 위해 가능한 모든 이벤트에 로그를 찍도록 했다.

 

그리고 HLS.js 에서도 같은 현상이 일어나는지도 확인해봤다.

 

우선 HLS.js의 경우 어떤 경우에서도 재생이 잘 됐고 다음과 같이 이벤트가 진행됐다.

  1. loadstart

  2. durationchange

  3. loadedmetadata

  4. durationchange

  5. loadeddata

  6. canplay

  7. canplaythrough

  8. play

video.js도 잘되는 경우엔 비슷하게 이벤트가 진행됐다.

 

자동 재생이 안되는 경우에는 이벤트가 다음과 같이 진행됐다.

  1. loadstart

  2. play

  3. durationchange

  4. loadedmetadata

loadedmetadata 이후에 loadeddata가 호출돼야하는데 더이상 진행이 되지 않았다.

 

이때 시킹바를 움직이거나 일시정지 후 다시 재생을 하면 제대로 재생이 됐다.

 

정확한 이유를 알 수 없었지만 중간에 play 이벤트가 먼저 호출되는게 문제가 있는 것 같아

 

autoplay를 false로 하고 loadedmetadata가 호출된 후 재생하도록 하니 잘 동작하는 것을 확인할 수 있었다.

 

참고 문헌

  1. developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events

     

반응형

'JS' 카테고리의 다른 글

[JS] 크롬에서 fetch 실패  (0) 2020.12.31
[JS] Electron으로 앱만들기  (0) 2020.08.13
[JS] PWA 만들기  (0) 2020.02.20
[JS] ejs SyntaxError  (0) 2020.01.25
[JS] RegExp 재사용할 때 문제 해결  (0) 2020.01.25
728x90
반응형

ffmpeg을 이용하여 동영상을 인코딩하는 데스크톱 앱을 만들어야 했다.

 

빠르게 만들기 위해 GitHub에 있을까하고 검색해보니 역시나 있었다.

 

만드는 과정에서 추가로 필요했던 기능들은 다음과 같았다.

  1. 새로 고침 막기

  2. 메뉴 수정

  3. asar로 빌드했을 때 실행 파일 불러오기

새로 고침을 막는 것은 우선 단축키가 아무 일도 하지 않도록 했다.

 

그리고 기본 메뉴에 새로 고침이 있었는데 이것 역시 제거하면서 불필요한 메뉴들을 모두 없앴다.

 

fluent-ffmpeg의 경우 ffmpeg 실행 파일을 불러 쓸 수 있었는데

 

asar로 빌드하는 경우 실행 파일도 같이 포함되어 만들어지나 파일 실행은 할 수 없었다.

 

그래서 ffmpeg, ffprobe 가 특정 디렉토리에 존재하도록 하고 이 디렉토리에 접근할 수 있어야 했다.

 

extraFiles를 이용하여 특정 디렉토리에 파일을 복사할 수 있었다.

 

그리고 getAppPath()로 특정 디렉토리에 접근하여 파일을 불러올 수 있었다.

 

작성한 코드 일부는 다음과 같다.

const { app, globalShortcut, BrowserWindow, Menu } = require('electron');
const path = require('path');
const ffmpeg = require('fluent-ffmpeg');
const isPackaged = process.mainModule.filename.indexOf('app.asar') !== -1;

if (process.platform === "darwin") {
  if (isPackaged) {
    ffmpeg.setFfmpegPath(path.join(path.dirname(app.getAppPath()), '..', './Resources', 'bin/ffmpeg'));
    ffmpeg.setFfprobePath(path.join(path.dirname(app.getAppPath()), '..', './Resources', 'bin/ffprobe'));
  } else {
    ffmpeg.setFfmpegPath(path.join(__dirname, '.', 'bin/osx/ffmpeg'));
    ffmpeg.setFfprobePath(path.join(__dirname, '.', 'bin/osx/ffprobe'));
  }
} else if (process.platform === 'win32') {
  ffmpeg.setFfmpegPath(path.join(__dirname, '.', 'bin/win32/ffmpeg.exe'));
  ffmpeg.setFfprobePath(path.join(__dirname, '.', 'bin/win32/ffprobe.exe'));
} else {
  ffmpeg.setFfmpegPath(path.join(__dirname, '.', 'bin/win64/ffmpeg.exe'));
  ffmpeg.setFfprobePath(path.join(__dirname, '.', 'bin/win64/ffprobe.exe'));
}

const createWindow = () => {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      devTools: false
    }
  });

  const isMac = process.platform === 'darwin';
  const template = [
    ...(isMac ? [{
      label: app.name,
      submenu: [
        { role: 'about' },
        { type: 'separator' },
        { role: 'hide' },
        { role: 'hideothers' },
        { role: 'unhide' },
        { type: 'separator' },
        { role: 'quit' }
      ]
    }] : []),
    {
      role: 'help',
      submenu: [
        {
          label: 'Learn More',
          click: async () => {
            await shell.openExternal('https://electronjs.org');
          }
        }
      ]
    }
  ];
  const menu = Menu.buildFromTemplate(template);
  Menu.setApplicationMenu(menu);
  win.setMenuBarVisibility(false);

  win.loadFile('index.html');

  win.webContents.openDevTools();
}

app.whenReady().then(createWindow);

app.on('browser-window-focus', () => {
    globalShortcut.register('CommandOrControl+R', () => {
    console.log('CommandOrControl+R is pressed: Shortcut Disabled');
});
globalShortcut.register('F5', () => {
    console.log('F5 is pressed: Shortcut Disabled');
});
});

app.on('browser-window-blur', () => {
    globalShortcut.unregister('CommandOrControl+R');
    globalShortcut.unregister('F5');
});
"build": {
  "productName": "My App",
  "appId": "com.my.app",
  "files": [
    "!bin/*"
  ],
  "extraFiles": [
    {
      "from": "bin/osx",
      "to": "Resources/bin",
      "filter": [
        "**/*"
      ]
    }
  ],
  "asar": true,
  "protocols": {
    "name": "myapp",
    "schemes": [
      "myapp"
    ]
  },
  "mac": {
    "target": [
      "dmg"
    ],
    "icon": "resources/icon.icns"
  },
  "dmg": {
    "internetEnabled": true
  },
  "win": {
    "target": [
      "zip",
      "nsis"
    ],
    "icon": "./resources/icon.ico"
  },
  "nsis": {
    "oneClick": false,
    "allowToChangeInstallationDirectory": true
  },
  "directories": {
    "buildResources": "./resources/installer/",
    "output": "./dist/",
    "app": "."
  }
}

 

참고 문헌

  1. https://github.com/likethemammal/electron-ffmpeg-example

  2. https://ffmpeg.zeranoe.com/builds/

  3. https://github.com/fluent-ffmpeg/node-fluent-ffmpeg

  4. https://www.electronjs.org/docs/api/menu

  5. https://discuss.atom.io/t/prevent-browserwindow-from-reloading/20541/3

반응형

'JS' 카테고리의 다른 글

[JS] 크롬에서 fetch 실패  (0) 2020.12.31
[JS] video.js 자동 재생이 안될 때 해결 방법  (0) 2020.09.24
[JS] PWA 만들기  (0) 2020.02.20
[JS] ejs SyntaxError  (0) 2020.01.25
[JS] RegExp 재사용할 때 문제 해결  (0) 2020.01.25
728x90
반응형

mp3 파일들을 연속으로 재생할 수 있는 웹페이지를 만들었다.

 

처음엔 단순하게 audio 태그를 이용하여 재생했다.

 

데스크톱에서 확인했을 때 잘 동작해서 문제가 없다고 생각했다.

 

그런데 모바일에서 확인해보니 처음 재생은 화면이 꺼져도 끝까지 잘 됐지만 다음 파일이 재생되지 않았다.

 

그래서 화면이 꺼지든가 브라우저가 백그라운드로 가도 재생이 되도록 해보려고 방법을 찾아봤다.

 

그러다가 PWA로 하면 원하는 기능이 되지 않을까 해서 찾아봤다.

 

찾아보니 PWA로 만든 음악 플레이어가 있어서 가능성이 보여 예제를 찾아 만들어 보기로 했다.

 

다음은 예제 코드를 참고하여 간단하게 PWA를 만든 코드 일부분이다.

 

manifest.json 파일을 만들어서 추가한다.

 

홈 화면에 추가했을 때 아이콘과 스플래시 화면이 나오도록 설정할 수 있다.

{
  "description": "Play mp3 files.",
  "display": "standalone",
  "icons": [
    {
      "src": "icon/icon-64.png",
      "sizes": "64x64",
      "type": "image/png"
    }
  ],
  "name": "PWA Test",
  "short_name": "PWA Test",
  "start_url": "/index.html",
  "background_color": "#3367D6",
  "theme_color": "#3367D6"
}

그리고 Service Worker를 등록하면 된다.

 

Service Worker는 브라우저가 백그라운드에서 실행하는 스크립트로 웹페이지와는 별개로 작동하며

 

웹페이지 또는 사용자 상호작용이 필요하지 않은 기능을 사용할 수 있게 해준다.

 

index.htmlService Worker를 등록하는 코드를 추가한다.

...
<head>
  <link rel="manifest" href="/manifest.json">
  <link rel="apple-touch-icon" sizes="180x180" href="/icons/icon-64.png">
</head>
<body>
  <script type="text/javascript">
    if('serviceWorker' in navigator) {
      navigator.serviceWorker
               .register('/pwa-examples/a2hs/sw.js')
               .then(function() { console.log('Service Worker Registered'); });
    }
  </script>
</body>
...

sw.js 파일에 다음 코드를 추가한다.

self.addEventListener('install', function(e) {
  e.waitUntil(
    caches.open('cache').then(function(cache) {
      return cache.addAll([
        '/',
        '/index.html',
        '/script.js',
        '/style.css',
        '/icon.png'
      ]);
    });
  );
});

self.addEventListener('fetch', function(e) {
  e.respondWith(
    caches.match(e.request).then(function(response) {
      return response || fetch(e.request);
    });
  );
});

iOS에서 사파리로 접속한 다음 _홈 화면에 추가_를 하면 설정한 아이콘 모양으로 홈 화면에 추가된다.

 

화면이 꺼지거나 앱을 종료해도 재생이 되는지 테스트했지만 재생이 되지 않았다.

 

하지만 안드로이드에서는 화면이 꺼지거나 앱을 꺼도 재생이 잘되는 것을 확인할 수 있었다.

 

참고 문헌

  1. https://github.com/mdn/pwa-examples

  2. https://developers.google.com/web/fundamentals/web-app-manifest

  3. https://developers.google.com/web/fundamentals/primers/service-workers?hl=ko

반응형

+ Recent posts