##// END OF EJS Templates
Add an Audio display class...
David Österberg -
Show More
@@ -4,7 +4,152 b' Authors : MinRK, gregcaporaso, dannystaple'
4 """
4 """
5 from os.path import exists, isfile, splitext, abspath, join, isdir
5 from os.path import exists, isfile, splitext, abspath, join, isdir
6 from os import walk, sep
6 from os import walk, sep
7 import base64
8 import struct
9 from io import BytesIO
10 import wave
11 import mimetypes
12
13 import numpy as np
14 from IPython.core.display import DisplayObject
15
16
17 class Audio(DisplayObject):
18 """Create an audio object.
19
20 When this object is returned by an input cell or passed to the
21 display function, it will result in Audio controls being displayed
22 in the frontend (only works in the notebook).
23
24 Parameters
25 ----------
26 data : numpy array, unicode, str or bytes
27 Can be a
28 * Numpy array containing the desired waveform,
29 * String containingvthe filename
30 * Bytestring containing raw PCM data or
31 * URL pointing to a file on the web.
32
33 If the array option is used the waveform will be normalized.
34
35 If a filename or url is used the format support will be browser
36 dependent.
37 url : unicode
38 A URL to download the data from.
39 filename : unicode
40 Path to a local file to load the data from.
41 embed : boolean
42 Should the image data be embedded using a data URI (True) or be
43 loaded using an <img> tag. Set this to True if you want the image
44 to be viewable later with no internet connection in the notebook.
45
46 Default is `True`, unless the keyword argument `url` is set, then
47 default value is `False`.
48 rate : integer
49 The sampling rate of the raw data.
50 Only required when data parameter is being used as an array
51 autoplay : bool
52 Set to True if the audio should immediately start playing.
53 Default is `False`.
54
55 Examples
56 --------
57
58 # Generate a sound
59 import numpy as np
60 framerate = 44100
61 t = np.linspace(0,5,framerate*5)
62 data = np.sin(2*np.pi*440*np.sin(10*t**2))
63 Audio(data,rate=framerate)
64
65 Audio("http://www.nch.com.au/acm/8k16bitpcm.wav")
66 Audio(url="http://media.bradsucks.net/albums/ooi-128/01_-_Brad_Sucks_-_Dropping_out_of_School.mp3")
67 Audio(url="http://www.w3schools.com/html/horse.ogg", embed=True)
68
69 Audio('/path/to/sound.wav')
70 Audio(filename='/path/to/sound.ogg')
71
72 Audio(b'RAW_WAV_DATA..)
73 Audio(data=b'RAW_WAV_DATA..)
7
74
75 """
76
77 def __init__(self, data=None, filename=None, url=None, embed=None, rate=None, autoplay=False):
78 if filename is None and url is None and data is None:
79 raise ValueError("No image data found. Expecting filename, url, or data.")
80 if embed is False and url is None:
81 raise ValueError("No url found. Expecting url when embed=False")
82
83 if url is not None and embed is not True:
84 self.embed = False
85 else:
86 self.embed = True
87 self.autoplay = autoplay
88 super(Audio, self).__init__(data=data, url=url, filename=filename)
89
90 if self.data is not None and not isinstance(self.data, bytes):
91 self.data = self._make_wav(data,rate)
92
93 def reload(self):
94 """Reload the raw data from file or URL."""
95 if self.embed:
96 super(Audio, self).reload()
97
98 if self.filename is not None:
99 self.mimetype = mimetypes.guess_type(self.filename)[0]
100 elif self.url is not None:
101 self.mimetype = mimetypes.guess_type(self.url)[0]
102 else:
103 self.mimetype = "audio/wav"
104
105
106 def _make_wav(self,data,rate):
107 """ Transform a numpy array to a PCM bytestring """
108 data = np.array(data)
109 scaled = np.int16(data/np.max(np.abs(data)) * 32767)
110 fp = BytesIO()
111 waveobj = wave.open(fp,mode='wb')
112 waveobj.setnchannels(1)
113 waveobj.setframerate(rate)
114 waveobj.setsampwidth(2)
115 waveobj.setcomptype('NONE','NONE')
116 waveobj.writeframes(b''.join([struct.pack('<h',x) for x in scaled]))
117 val = fp.getvalue()
118 waveobj.close()
119 return val
120
121 def _data_and_metadata(self):
122 """shortcut for returning metadata with url information, if defined"""
123 md = {}
124 if self.url:
125 md['url'] = self.url
126 if md:
127 return self.data, md
128 else:
129 return self.data
130
131 def _repr_html_(self):
132 src = """
133 <audio controls="controls" {autoplay}>
134 <source src="{src}" type="{type}" />
135 Your browser does not support the audio element.
136 </audio>
137 """
138 return src.format(src=self.src_attr(),type=self.mimetype, autoplay=self.autoplay_attr())
139
140 def src_attr(self):
141 if self.embed and (self.data is not None):
142 return """data:{type};base64,{base64}""".format(type=self.mimetype, base64=base64.encodestring(self.data))
143 elif self.url is not None:
144 return self.url
145 else:
146 return ""
147
148 def autoplay_attr(self):
149 if(self.autoplay):
150 return 'autoplay="autoplay"'
151 else:
152 return ''
8
153
9 class IFrame(object):
154 class IFrame(object):
10 """
155 """
General Comments 0
You need to be logged in to leave comments. Login now