In [ ]:
import os
import random, string

import numpy as np
np.set_printoptions(precision=3)

import matplotlib.pyplot as plt

#import re

In [ ]:
# pip install soundfile, librosa
import soundfile
import librosa
import librosa.display

from IPython.display import display as notebook_display
from IPython.display import Audio as notebook_audio
from IPython.display import HTML as notebook_html

tmp_audio_playback_dir = './data/tmp-audio-playback/'
os.makedirs(tmp_audio_playback_dir, exist_ok=True)

In [ ]:
audio_filenames = [ './librivox/guidetomen_%02d_rowland_64kb.mp3' % (i,) for i in [1,2,3]]
audio_filenames

#mel_filenames = [ f.replace('.mp3', '.melspectra.hkl') for f in audio_filenames ]

In [ ]:
audio_filename = './librivox/guidetomen_02_rowland_64kb.mp3'

audio_samples, _sample_rate = librosa.core.load(audio_filename, sr=None)
audio_samples = audio_samples/np.max(audio_samples)

#audio_samples, 
_sample_rate

In [ ]:
def play_audio_samples(np_samples, autoplay=False):
    hsh = ''.join(random.choices(string.ascii_uppercase + string.digits, k=8))
    f = tmp_audio_playback_dir + '%s.wav' % (hsh,)
    soundfile.write(f, np_samples, samplerate=_sample_rate)

    if True or np_samples.shape[0]<100*1000:
        plt.figure(figsize=(12,2))
        librosa.display.waveplot(np_samples, sr=_sample_rate)
        plt.grid(True)
        plt.show()
        
    notebook_display( 
        #notebook_html('<code id="%s">Javascript Loaded</code>' % (hsh,)),
        notebook_html('<span id="%s"></span>' % (hsh,)),
        notebook_audio(f, rate=_sample_rate, autoplay=autoplay)
    )
    return hsh

In [ ]:
# https://www.sitepoint.com/community/t/multiple-clickable-audio-timestamps/273260/9

notebook_html("""<script type="text/Javascript">
function get_next_display_ele(id, selector) {
    var pre_div=$(id);
    var ctrl = pre_div.parent().parent().next().find(selector);
    return $(ctrl)[0];
}
function insertAtCaret(areaId, text, combine_lf) {
    var txtarea = document.getElementById(areaId);
    var scrollPos = txtarea.scrollTop;
    var caretPos = txtarea.selectionStart;
    
    var front = (txtarea.value).substring(0, caretPos);
    var back = (txtarea.value).substring(txtarea.selectionEnd, txtarea.value.length);
    if(combine_lf) {
      var lf='\\n';
      if(front.substr(-1,1)==lf && text.substr(0,1)==lf) {
        text=text.substr(1);
      }
      if(back.substr(0,1)==lf && text.substr(-1,1)==lf) {
        back=back.substr(1);
      }
    }
    txtarea.value = front + text + back;
    caretPos = caretPos + text.length;
    txtarea.selectionStart = caretPos;
    txtarea.selectionEnd = caretPos;
    txtarea.focus();
    txtarea.scrollTop = scrollPos;
}
</script>""")

In [ ]:
txt_filename = audio_filename.replace('.mp3', '.txt')
txt_for_audio = ''
try:
    with open(txt_filename, 'rt') as f:
        txt_for_audio=f.read()
    print("%s loaded" % txt_filename)
except:
    print("%s : File not found" % txt_filename)

In [ ]:
audio_id=play_audio_samples(audio_samples)
#audio_id

In [ ]:
notebook_html("""
<textarea rows=20 cols=70 id={id}>{content}</textarea>
""".format(id=audio_id+'_tb', content=txt_for_audio))

In [ ]:
# https://stackoverflow.com/questions/1064089/
#   inserting-a-text-where-cursor-is-using-javascript-jquery

notebook_html("""<script type="text/Javascript">
var selector = '%s';
var audio_ele=get_next_display_ele('#'+selector, 'audio') || {};
$('#'+selector+'_tb').off('keypress').on('keypress', function(ev) { 
    //alert(ev, ev.which); 
    if( ev.which == 126) { // 126==tilde
      var ts = "\\n#TS "+(audio_ele.currentTime || 0)+"\\n";
      insertAtCaret(selector+'_tb', ts, true);
      ev.preventDefault();
    }
});
</script>""" % (audio_id, ))

In [ ]:
audio_id

In [ ]:
# Save the annotated text back to disk : 
#   Need to retrieve it from javascript textbox
updated_txt = None

notebook_html("""<script type="text/Javascript">
var kernel = IPython.notebook.kernel;
var selector = '%s';
var txt=$('#'+selector+'_tb').val();
var txt_clean=txt.replace('"', '\\"');
//alert(txt_clean);
//kernel.execute("updated_txt=", {iopub: {output: handle_python_output}}, {silent:false});
kernel.execute('updated_txt=\"\"\"'+txt_clean+'\"\"\"');
</script>""" % (audio_id, ))

In [ ]:
#print( updated_txt )

In [ ]:
#if updated_txt is not None:
#    with open(txt_filename, 'wt') as f:
#        f.write(updated_txt)

In [ ]: