Commit 4e4b74a6 authored by Jerome Wu's avatar Jerome Wu

Add theora and vorbis build scripts, tests and examples

parent b1d5fc0c
...@@ -33,6 +33,16 @@ $ bash build.sh ...@@ -33,6 +33,16 @@ $ bash build.sh
If nothing goes wrong, you can find JavaScript files in `wasm/dist`. If nothing goes wrong, you can find JavaScript files in `wasm/dist`.
## Test
Once the build completes, you can test with following scripts:
```
$ cd wasm
$ npm install
$ npm test
```
## Configuration ## Configuration
#### Base #### Base
...@@ -45,9 +55,12 @@ If nothing goes wrong, you can find JavaScript files in `wasm/dist`. ...@@ -45,9 +55,12 @@ If nothing goes wrong, you can find JavaScript files in `wasm/dist`.
- x264 (mp4): 0.160.x - x264 (mp4): 0.160.x
- x265 (mp4): 3.4 (only works with `-pix_fmt yuv420p10le` and `-pix_fmt yuv420p12le`) - x265 (mp4): 3.4 (only works with `-pix_fmt yuv420p10le` and `-pix_fmt yuv420p12le`)
- libvpx (webm): 1.9.0 - libvpx (webm): 1.9.0
- theora (ogv): 1.1.1
#### Audio #### Audio
- wavpack (wav): 5.3.0 - wavpack (wav): 5.3.0
- lame (mp3): 3.100 - lame (mp3): 3.100
- fdk-aac (aac); 2.0.1 - fdk-aac (aac); 2.0.1
- ogg: 1.3.4
- vorbis (ogg): 1.3.6
...@@ -21,9 +21,11 @@ $SCRIPT_ROOT/build-lame.sh ...@@ -21,9 +21,11 @@ $SCRIPT_ROOT/build-lame.sh
# build fdk-aac # build fdk-aac
$SCRIPT_ROOT/build-fdk-aac.sh $SCRIPT_ROOT/build-fdk-aac.sh
# build ogg # build ogg
# $SCRIPT_ROOT/build-ogg.sh $SCRIPT_ROOT/build-ogg.sh
# build vorbis # build vorbis
# $SCRIPT_ROOT/build-vorbis.sh $SCRIPT_ROOT/build-vorbis.sh
# build theora
$SCRIPT_ROOT/build-theora.sh
# configure FFmpeg with Emscripten # configure FFmpeg with Emscripten
$SCRIPT_ROOT/configure-ffmpeg.sh $SCRIPT_ROOT/configure-ffmpeg.sh
# build ffmpeg.wasm core # build ffmpeg.wasm core
......
...@@ -9,7 +9,7 @@ FLAGS=( ...@@ -9,7 +9,7 @@ FLAGS=(
-I. -I./fftools -I$BUILD_DIR/include -I. -I./fftools -I$BUILD_DIR/include
-Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavresample -Llibavutil -Llibpostproc -Llibswscale -Llibswresample -L$BUILD_DIR/lib -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavresample -Llibavutil -Llibpostproc -Llibswscale -Llibswresample -L$BUILD_DIR/lib
-Wno-deprecated-declarations -Wno-pointer-sign -Wno-implicit-int-float-conversion -Wno-switch -Wno-parentheses -Qunused-arguments -Wno-deprecated-declarations -Wno-pointer-sign -Wno-implicit-int-float-conversion -Wno-switch -Wno-parentheses -Qunused-arguments
-lavdevice -lavfilter -lavformat -lavcodec -lswresample -lswscale -lavutil -lpostproc -lm -lx264 -lx265 -lvpx -lwavpack -lmp3lame -lfdk-aac -pthread -lavdevice -lavfilter -lavformat -lavcodec -lswresample -lswscale -lavutil -lpostproc -lm -lx264 -lx265 -lvpx -lwavpack -lmp3lame -lfdk-aac -lvorbis -lvorbisenc -lvorbisfile -logg -ltheora -ltheoraenc -ltheoradec -pthread
fftools/ffmpeg_opt.c fftools/ffmpeg_filter.c fftools/ffmpeg_hw.c fftools/cmdutils.c fftools/ffmpeg.c fftools/ffmpeg_opt.c fftools/ffmpeg_filter.c fftools/ffmpeg_hw.c fftools/cmdutils.c fftools/ffmpeg.c
-o wasm/dist/ffmpeg-core.js -o wasm/dist/ffmpeg-core.js
-s USE_SDL=2 # use SDL2 -s USE_SDL=2 # use SDL2
......
#!/bin/bash
set -euo pipefail
source $(dirname $0)/var.sh
LIB_PATH=third_party/theora
CFLAGS="-s USE_PTHREADS=1 $OPTIM_FLAGS -I$BUILD_DIR/include"
LDFLAGS="-L$BUILD_DIR/lib"
CONF_FLAGS=(
--prefix=$BUILD_DIR # install library in a build directory for FFmpeg to include
--host=i686-linux # use i686 linux
--enable-shared=no # disable shared library
--enable-docs=no
--enable-fast-install=no
--disable-spec
--disable-asm
--disable-examples
--disable-oggtest # disable ogg tests
--disable-vorbistest # disable vorbis tests
--disable-sdltest # disable sdl tests
)
echo "CONF_FLAGS=${CONF_FLAGS[@]}"
(cd $LIB_PATH && \
CFLAGS=$CFLAGS LDFLAGS=$LDFLAGS emconfigure ./autogen.sh "${CONF_FLAGS[@]}")
emmake make -C $LIB_PATH clean
emmake make -C $LIB_PATH install -j
...@@ -10,12 +10,16 @@ CONF_FLAGS=( ...@@ -10,12 +10,16 @@ CONF_FLAGS=(
--prefix=$BUILD_DIR # install library in a build directory for FFmpeg to include --prefix=$BUILD_DIR # install library in a build directory for FFmpeg to include
--host=i686-linux # use i686 linux --host=i686-linux # use i686 linux
--enable-shared=no # disable shared library --enable-shared=no # disable shared library
--disable-oggtest # disable tests --enable-docs=no
--enable-examples=no
--enable-fast-install=no --enable-fast-install=no
--disable-oggtest # disable oggtests
) )
echo "CONF_FLAGS=${CONF_FLAGS[@]}" echo "CONF_FLAGS=${CONF_FLAGS[@]}"
(cd $LIB_PATH && \ (cd $LIB_PATH && \
emconfigure ./autogen.sh && \ emconfigure ./autogen.sh && \
CFLAGS=$CFLAGS LDFLAGS=$LDFLAGS emconfigure ./configure "${CONF_FLAGS[@]}") CFLAGS=$CFLAGS LDFLAGS=$LDFLAGS emconfigure ./configure "${CONF_FLAGS[@]}")
# (cd $LIB_PATH && \
# CFLAGS=$CFLAGS LDFLAGS=$LDFLAGS emconfigure ./autogen.sh "${CONF_FLAGS[@]}")
emmake make -C $LIB_PATH clean emmake make -C $LIB_PATH clean
emmake make -C $LIB_PATH install -j emmake make -C $LIB_PATH install -j
...@@ -52,13 +52,15 @@ FFMPEG_CONFIG_FLAGS_BASE=( ...@@ -52,13 +52,15 @@ FFMPEG_CONFIG_FLAGS_BASE=(
--enable-libwavpack # enable libwavpack --enable-libwavpack # enable libwavpack
--enable-libmp3lame # enable libmp3lame --enable-libmp3lame # enable libmp3lame
--enable-libfdk-aac # enable libfdk-aac --enable-libfdk-aac # enable libfdk-aac
# --enable-libvorbis # enable libvorbis --enable-libtheora # enable libtheora
--enable-libvorbis # enable libvorbis
--disable-debug # disable debug info, required by closure --disable-debug # disable debug info, required by closure
--disable-runtime-cpudetect # disable runtime cpu detect --disable-runtime-cpudetect # disable runtime cpu detect
--disable-autodetect # disable external libraries auto detect --disable-autodetect # disable external libraries auto detect
--extra-cflags="$CFLAGS" --extra-cflags="$CFLAGS"
--extra-cxxflags="$CFLAGS" --extra-cxxflags="$CFLAGS"
--extra-ldflags="$LDFLAGS" --extra-ldflags="$LDFLAGS"
--pkg-config-flags="--static"
--nm="llvm-nm" --nm="llvm-nm"
--ar=emar --ar=emar
--as=llvm-as --as=llvm-as
......
...@@ -38,6 +38,7 @@ const runFFmpeg = async (ifilename, data, args, ofilename) => { ...@@ -38,6 +38,7 @@ const runFFmpeg = async (ifilename, data, args, ofilename) => {
console.log(m); console.log(m);
}, },
print: (m) => { print: (m) => {
console.log(m);
if (m.startsWith('FFMPEG_END')) { if (m.startsWith('FFMPEG_END')) {
resolve(); resolve();
} }
......
<html>
<head>
<style>
html, body {
margin: 0;
width: 100%;
height: 100%
}
body {
display: flex;
flex-direction: column;
align-items: center;
}
</style>
</head>
<body>
<h3>Upload a video to transcode to ogv (theora) and play!</h3>
<video id="output-video" controls></video><br/>
<input type="file" id="uploader">
<p id="message">Upload a video</p>
<script type="text/javascript" src="./js/utils.js"></script>
<script type="text/javascript">
const message = document.getElementById('message');
const transcode = async ({ target: { files } }) => {
const IN_FILE_NAME = 'video.avi';
const OUT_FILE_NAME = 'video.ogv';
const args = ['-i', IN_FILE_NAME, '-c:v', 'libtheora', OUT_FILE_NAME];
message.innerHTML = 'Writing file to MEMFS';
const data = new Uint8Array(await readFromBlobOrFile(files[0]));
const now = Date.now();
console.time(`[${now}] ${files[0].name} execution time`);
message.innerHTML = 'Start to transcode';
const { file } = await runFFmpeg(IN_FILE_NAME, data, args, OUT_FILE_NAME)
const video = document.getElementById('output-video');
video.src = URL.createObjectURL(new Blob([file.buffer], { type: 'video/ogv' }));
console.timeEnd(`[${now}] ${files[0].name} execution time`);
};
document.getElementById('uploader').addEventListener('change', transcode);
</script>
<script type="text/javascript" src="../../dist/ffmpeg-core.js"></script>
</body>
</html>
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
</style> </style>
</head> </head>
<body> <body>
<h3>Upload a wav file to transcode to aac and play!</h3> <h3>Upload a wav file to transcode to ogg and play!</h3>
<audio id="output-audio" controls></audio><br/> <audio id="output-audio" controls></audio><br/>
<input type="file" id="uploader"> <input type="file" id="uploader">
<p id="message">Upload a wav file</p> <p id="message">Upload a wav file</p>
......
module.exports = { module.exports = {
TIMEOUT: 60000, TIMEOUT: 120000,
}; };
const fs = require('fs');
const path = require('path');
const { TIMEOUT } = require('./config');
const { runFFmpeg } = require('./utils');
const IN_FILE_NAME = 'video-1s.avi';
const OUT_FILE_NAME = 'video.ogv';
const OGV_SIZE = 29561;
let aviData = null;
beforeAll(() => {
aviData = Uint8Array.from(fs.readFileSync(path.join(__dirname, 'data', IN_FILE_NAME)));
});
test('convert avi to ogv', async () => {
const args = ['-i', IN_FILE_NAME, '-c:v', 'libtheora', OUT_FILE_NAME];
const { fileSize } = await runFFmpeg(IN_FILE_NAME, aviData, args, OUT_FILE_NAME);
expect(fileSize).toBe(OGV_SIZE);
}, TIMEOUT);
...@@ -4,7 +4,7 @@ const { TIMEOUT } = require('./config'); ...@@ -4,7 +4,7 @@ const { TIMEOUT } = require('./config');
const { runFFmpeg } = require('./utils'); const { runFFmpeg } = require('./utils');
const IN_FILE_NAME = 'audio-1s.wav'; const IN_FILE_NAME = 'audio-1s.wav';
const OUT_FILE_NAME = 'audio.ogg'; const OUT_FILE_NAME = 'audio.ogg';
const OGG_SIZE = 4239; const OGG_SIZE = 7712;
let wavData = null; let wavData = null;
beforeAll(() => { beforeAll(() => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment