web: Crash when serializing objects with bytes fields
### Problem

For some reason the web interface is not working correctly. I can't actually get it to search for anything. When you type something into the search box nothing happens except for the following text being printed to the terminal.

Running this command in verbose (`-vv`) mode:

```sh
$ beet -vv web
```
Then searching for something in the web interface gives this problem:

```
~
➔ beet -vv web
 * Running on http://127.0.0.1:8337/ (Press CTRL+C to quit)
127.0.0.1 - - [30/Apr/2017 11:05:15] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [30/Apr/2017 11:05:22] "GET /item/query/isabel HTTP/1.1" 200 -
Error on request:
Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/werkzeug/serving.py", line 209, in run_wsgi
    execute(self.server.app)
  File "/usr/lib/python3.6/site-packages/werkzeug/serving.py", line 199, in execute
    for data in application_iter:
  File "/usr/lib/python3.6/site-packages/werkzeug/wsgi.py", line 704, in __next__
    return self._next()
  File "/usr/lib/python3.6/site-packages/werkzeug/wrappers.py", line 81, in _iter_encoded
    for item in iterable:
  File "/usr/lib/python3.6/site-packages/beetsplug/web/__init__.py", line 74, in json_generator
    yield json.dumps(_rep(item, expand=expand))
  File "/usr/lib/python3.6/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python3.6/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.6/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python3.6/json/encoder.py", line 180, in default
    o.__class__.__name__)
TypeError: Object of type 'bytes' is not JSON serializable
```

### Setup

* OS: Arch Linux
* Python version: Python 3.6
* beets version: 1.4.3
* Turning off plugins made problem go away (yes/no): no, the problem is with the web plugin

My configuration (output of `beet config`) is:

```yaml
directory: ~/Music
library: ~/Music/musicLibrary.db

import:
    move: yes

plugins: chroma web
acoustid:
    apikey: REDACTED
web:
    host: 127.0.0.1
    port: 8337
    cors: ''
chroma:
    auto: yes
```

diff --git a/beetsplug/web/__init__.py b/beetsplug/web/__init__.py
index 3c18ebd5d..c154b0cf4 100644
--- a/beetsplug/web/__init__.py
+++ b/beetsplug/web/__init__.py
@@ -25,6 +25,7 @@ from flask import g
 from werkzeug.routing import BaseConverter, PathConverter
 import os
 import json
+import base64
 
 
 # Utilities.
@@ -42,6 +43,11 @@ def _rep(obj, expand=False):
         else:
             del out['path']
 
+        # Filter all bytes attributes and convert them to strings
+        for key, value in out.items():
+            if isinstance(out[key], bytes):
+                out[key] = base64.b64encode(out[key]).decode('ascii')
+
         # Get the size (in bytes) of the backing file. This is useful
         # for the Tomahawk resolver API.
         try:
['beetsplug/web/__init__.py']