Snippet Wednesday - Dynamic Audio and GIFs in a WebView!

Hey everyone!

For this week’s Snippet Wednesday I have a small app that activates audio and a GIF in the WebView.

what is this useful for?
Let’s say you would like to add some more, dynamic content that is limited by html, then you can use CSS and Javascript to extend your functionality.

This app has an audio player and dynamic GIF to show you how it done. The app will hide the GIF when the audio is not playing.

what you will need to add to your app folder:

  • You will need an awesome piece of audio to add to your app
  • A cool GIF to add to your application

full code
The full functional app-code for this example can be found here:

from viktor import ViktorController
from viktor.parametrization import ViktorParametrization, SetParamsButton, BooleanField
from viktor.result import SetParamsResult
from viktor.views import WebView, WebResult
import base64
from pathlib import Path
from io import StringIO
  
def base64_encoding(data: bytes):
    return base64.b64encode(data).decode()
  
class Parametrization(ViktorParametrization):
    make_web_view = SetParamsButton('🦄 Click here to activate 🦄', method='set_html', flex=100)
    boolean_html = BooleanField('show content', default=False, visible=False)
  
class Controller(ViktorController):
    label = 'audio demonstration app'
    parametrization = Parametrization
  
    @WebView('Audio player', duration_guess=1)
    def get_gif_view(self, params, **kwargs):
        audio_path = Path(__file__).parent / 'my_awesome_audio.mp3'
        gif_path = Path(__file__).parent/'giphy.gif'
        with open(audio_path, 'rb') as f:
            audio = base64_encoding(f.read())
        with open(gif_path, 'rb') as file:
            gif_data=base64_encoding(file.read())
        if not params.boolean_html:
            html_string = f'''
<!DOCTYPE html>
<html>
</html>'''
  
        else:
            html_string = f'''
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Audio with GIF</title>
    <style>
        #gif {{
            display: none;
        }}
    </style>
</head>
<body style="height:100%;">

    <audio id="audio" controls autoplay>
        <source src="data:audio/mp3;base64,{audio}" type="audio/mpeg">
        Your browser does not support the audio element.
    </audio>
  
    <img id="gif" src="data:gif_data/gif;base64,{gif_data}" alt="Playing GIF" style="display: block;width: 65%;">>
    
    <script>
        // Get references to the audio and GIF elements
        const audio = document.getElementById('audio');
        const gif = document.getElementById('gif');
  
        // Add an event listener to the play button of the audio player
        audio.addEventListener('play', () => {{
            
            gif.style.display = 'block';
        }});
  
        // Add an event listener to the pause button of the audio player
        audio.addEventListener('pause', () => {{
            // When pause is clicked, hide the GIF
            gif.style.display = 'none';
        }});
    </script>
</body>
</html>'''
        return WebResult(html=StringIO(html_string))
    
    def set_html(self):
        return SetParamsResult({
            "boolean_html": True
        })

The result will amaze you :wink:

gif-view

3 Likes

Thanks Thomas!!

I made a little public app from it, enjoy sending it around to your friends :wink: