├── README.md ├── Dockerfile └── .github └── workflows └── build.yml /README.md: -------------------------------------------------------------------------------- 1 | # Audio Waveform Image Generator Docker Container 2 | 3 | ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/realies/audiowaveform-docker/build.yml) 4 | ![Docker Build](https://img.shields.io/docker/automated/realies/audiowaveform) 5 | ![Docker Pulls](https://img.shields.io/docker/pulls/realies/audiowaveform) 6 | ![Docker Image Size](https://img.shields.io/docker/image-size/realies/audiowaveform) 7 | 8 | **audiowaveform** is a C++ command-line application that generates waveform data 9 | from either MP3, WAV, FLAC, Ogg Vorbis, or Opus format audio files. Waveform data can 10 | be used to produce a visual rendering of the audio, similar in appearance to 11 | audio editing applications. The code for the application binary can be found [here](https://github.com/bbc/audiowaveform). 12 | Compiled for 386, amd64, arm/v6, arm/v7, arm64, ppc64le, s390x. 13 | 14 | ![Example Waveform](https://raw.githubusercontent.com/bbc/audiowaveform/master/doc/example.png "Example Waveform") 15 | 16 | Waveform data files are saved in either binary format (.dat) or JSON (.json). 17 | Given an input waveform data file, **audiowaveform** can also render the audio 18 | waveform as a PNG image at a given time offset and zoom level. 19 | 20 | ## Typical Usage 21 | 22 | ##### Using Docker CLI 23 | ``` 24 | alias awf='docker run --rm -v `pwd`:/tmp -w /tmp realies/audiowaveform' 25 | awf -i input.wav -o output.png 26 | ``` 27 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:edge as builder 2 | ENV COMMIT e26bb08 3 | RUN apk add --no-cache autoconf automake g++ gcc libtool make nasm ncurses-dev && \ 4 | wget https://downloads.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gz && \ 5 | tar -xf lame-3.100.tar.gz && \ 6 | cd lame-3.100 && \ 7 | # fix for parallel builds 8 | mkdir -p libmp3lame/i386/.libs && \ 9 | # fix for pic build with new nasm 10 | sed -i -e '/define sp/s/+/ + /g' libmp3lame/i386/nasm.h && \ 11 | aclocal && automake --force --add-missing && \ 12 | ./configure \ 13 | --build=$CBUILD \ 14 | --host=$CHOST \ 15 | --prefix=/usr \ 16 | --enable-nasm \ 17 | --disable-mp3x \ 18 | --disable-shared \ 19 | --with-pic && \ 20 | make -j $(nproc) && \ 21 | make test && \ 22 | make install 23 | RUN apk add --no-cache autoconf automake g++ gcc libtool gettext git make && \ 24 | git clone https://github.com/xiph/opus && \ 25 | cd opus && \ 26 | ./autogen.sh && \ 27 | ./configure \ 28 | --prefix=/usr \ 29 | --sysconfdir=/etc \ 30 | --localstatedir=/var \ 31 | --enable-custom-modes && \ 32 | make -j $(nproc) && \ 33 | make check && \ 34 | make install 35 | RUN apk add --no-cache cmake g++ gcc git samurai && \ 36 | git clone https://github.com/xiph/ogg && \ 37 | cd ogg && \ 38 | cmake -B build -G Ninja \ 39 | -DCMAKE_INSTALL_PREFIX=/usr \ 40 | -DCMAKE_INSTALL_LIBDIR=lib \ 41 | -DBUILD_SHARED_LIBS=False \ 42 | -DCMAKE_BUILD_TYPE=Release \ 43 | $CMAKE_CROSSOPTS && \ 44 | cmake --build build -j $(nproc) && \ 45 | ctest -j $(nproc) && \ 46 | cmake --install build 47 | RUN apk add --no-cache autoconf automake libtool g++ gcc gettext git !libiconv make pkgconfig && \ 48 | git clone https://github.com/xiph/flac && \ 49 | cd flac && \ 50 | ./autogen.sh && \ 51 | ./configure \ 52 | --prefix=/usr \ 53 | --enable-shared=no \ 54 | --enable-ogg \ 55 | --disable-rpath \ 56 | --with-pic && \ 57 | make -j $(nproc) && \ 58 | make check || true && \ 59 | make install 60 | RUN apk add --no-cache alsa-lib-dev cmake git flac-dev libvorbis-dev linux-headers python3 samurai && \ 61 | git clone https://github.com/libsndfile/libsndfile && \ 62 | cd libsndfile && \ 63 | cmake -B build -G Ninja \ 64 | -DBUILD_SHARED_LIBS=OFF \ 65 | -DCMAKE_BUILD_TYPE=MinSizeRel \ 66 | -DCMAKE_INSTALL_PREFIX=/usr \ 67 | -DENABLE_MPEG=ON && \ 68 | cmake --build build -j $(nproc) && \ 69 | cd build && \ 70 | CTEST_OUTPUT_ON_FAILURE=TRUE ctest -E write_read_test_sd2 && \ 71 | cd .. && \ 72 | cmake --install build 73 | RUN apk add --no-cache cmake g++ gcc git samurai zlib-dev && \ 74 | git clone https://codeberg.org/tenacityteam/libid3tag && \ 75 | cd libid3tag && \ 76 | cmake -B build -G Ninja \ 77 | -DBUILD_SHARED_LIBS=OFF \ 78 | -DCMAKE_BUILD_TYPE=MinSizeRel \ 79 | -DENABLE_TESTS=YES \ 80 | -DCMAKE_INSTALL_PREFIX=/usr \ 81 | -DCMAKE_INSTALL_LIBDIR=lib && \ 82 | cmake --build build -j $(nproc) && \ 83 | cd build && \ 84 | CTEST_OUTPUT_ON_FAILURE=TRUE ctest && \ 85 | cd .. && \ 86 | cmake --install build 87 | RUN apk add --no-cache boost-dev boost-static cmake g++ gcc gd-dev git libgd libmad-dev libpng-dev libpng-static libvorbis-static make zlib-dev zlib-static && \ 88 | git clone -n https://github.com/bbc/audiowaveform.git && \ 89 | cd audiowaveform && \ 90 | git checkout ${COMMIT} && \ 91 | git clone https://github.com/google/googletest && \ 92 | mkdir build && \ 93 | cd build && \ 94 | cmake -DCMAKE_CXX_STANDARD=14 -D ENABLE_TESTS=1 -D BUILD_STATIC=1 .. && \ 95 | make -j $(nproc) && \ 96 | /audiowaveform/build/audiowaveform_tests || true && \ 97 | make install && \ 98 | strip /usr/local/bin/audiowaveform 99 | FROM alpine:edge 100 | RUN apk add --no-cache libstdc++ 101 | COPY --from=builder /usr/local/bin/audiowaveform /usr/local/bin/audiowaveform 102 | ENTRYPOINT [ "audiowaveform" ] 103 | CMD [ "--help" ] 104 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Update Audiowaveform Docker Image 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 * * *' # Daily at 00:00 UTC 6 | workflow_dispatch: 7 | push: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | check-and-update: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout audiowaveform-docker repository 16 | uses: actions/checkout@v4 17 | with: 18 | repository: 'realies/audiowaveform-docker' 19 | path: 'audiowaveform-docker' 20 | 21 | - name: Get latest commit and check for tag from audiowaveform 22 | id: latest_commit_and_tag 23 | uses: actions/github-script@v7 24 | with: 25 | script: | 26 | const commitResult = await github.rest.repos.getBranch({ 27 | owner: 'bbc', 28 | repo: 'audiowaveform', 29 | branch: 'master', 30 | }); 31 | const commit = commitResult.data.commit.sha.substring(0, 7); 32 | console.log(`latest commit SHA: ${commit}`); 33 | core.setOutput('commit', commit); 34 | 35 | const tagsResult = await github.rest.repos.listTags({ 36 | owner: 'bbc', 37 | repo: 'audiowaveform', 38 | }); 39 | const tag = tagsResult.data.find(t => t.commit.sha.startsWith(commit))?.name || ''; 40 | console.log(`tag associated with the latest commit: ${tag}`); 41 | core.setOutput('tag', tag); 42 | 43 | - name: Read current commit in Dockerfile 44 | id: current_commit 45 | working-directory: ./audiowaveform-docker 46 | run: | 47 | COMMIT=$(grep -oP '(?<=ENV COMMIT )\S+' Dockerfile) 48 | echo "current COMMIT in Dockerfile: $COMMIT" 49 | echo "commit=$COMMIT" >> $GITHUB_OUTPUT 50 | 51 | - name: Update Dockerfile if needed 52 | if: steps.current_commit.outputs.commit != steps.latest_commit_and_tag.outputs.commit 53 | working-directory: ./audiowaveform-docker 54 | run: | 55 | echo "updating ENV COMMIT in Dockerfile from ${CURRENT_COMMIT} to ${LATEST_COMMIT}" 56 | sed -i "s/^ENV COMMIT ${CURRENT_COMMIT}/ENV COMMIT ${LATEST_COMMIT}/" Dockerfile 57 | env: 58 | CURRENT_COMMIT: ${{ steps.current_commit.outputs.commit }} 59 | LATEST_COMMIT: ${{ steps.latest_commit_and_tag.outputs.commit }} 60 | 61 | - name: Set up QEMU 62 | uses: docker/setup-qemu-action@v3 63 | 64 | - name: Set up Docker Buildx 65 | uses: docker/setup-buildx-action@v3 66 | 67 | - name: Login to Docker Hub 68 | uses: docker/login-action@v3 69 | with: 70 | username: ${{ secrets.DOCKER_USERNAME }} 71 | password: ${{ secrets.DOCKER_PASSWORD }} 72 | 73 | - name: Prepare Docker Tags 74 | id: prepare_tags 75 | working-directory: ./audiowaveform-docker 76 | run: | 77 | if [[ ! -z "$TAG_NAME" ]]; then 78 | echo "tags=realies/audiowaveform:$TAG_NAME,realies/audiowaveform:latest" >> $GITHUB_OUTPUT 79 | else 80 | echo "tags=realies/audiowaveform:latest" >> $GITHUB_OUTPUT 81 | fi 82 | env: 83 | TAG_NAME: ${{ steps.latest_commit_and_tag.outputs.tag }} 84 | 85 | - name: Build and push Docker image 86 | if: | 87 | steps.current_commit.outputs.commit != steps.latest_commit_and_tag.outputs.commit || 88 | (github.event_name == 'push' && !contains(github.event.head_commit.message, 'update to')) 89 | uses: docker/build-push-action@v5 90 | with: 91 | context: ./audiowaveform-docker 92 | file: ./audiowaveform-docker/Dockerfile 93 | push: true 94 | tags: ${{ steps.prepare_tags.outputs.tags }} 95 | platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x 96 | # Ensure Buildx is used with cache 97 | cache-from: type=registry,ref=realies/audiowaveform:cache 98 | cache-to: type=inline,mode=max,ref=realies/audiowaveform:cache 99 | 100 | - name: Commit Dockerfile if needed 101 | if: steps.current_commit.outputs.commit != steps.latest_commit_and_tag.outputs.commit 102 | working-directory: ./audiowaveform-docker 103 | run: | 104 | git config user.email "${{ secrets.USER_EMAIL }}" 105 | git config user.name "${{ secrets.USER_NAME }}" 106 | git add Dockerfile 107 | git commit -m "update to ${{ steps.latest_commit_and_tag.outputs.commit }}" 108 | git push 109 | --------------------------------------------------------------------------------