Skip to content

Commit

Permalink
Merge branch 'master' into production
Browse files Browse the repository at this point in the history
  • Loading branch information
vpetersson committed Nov 25, 2017
2 parents 8f329b0 + e06cfad commit 7bef424
Show file tree
Hide file tree
Showing 17 changed files with 480 additions and 83 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ addons:
- net-tools
- mplayer
- python-setuptools
before_install:
- sudo add-apt-repository ppa:mc3man/trusty-media -y
- sudo apt-get update -q
- sudo apt-get install ffmpeg
install:
- pip install -U pip
- pip install -r requirements.txt
Expand Down
17 changes: 16 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,22 @@ FROM debian:stretch
MAINTAINER Viktor Petersson <[email protected]>

RUN apt-get update && \
apt-get -y install build-essential git-core net-tools python-netifaces python-simplejson python-imaging python-dev sqlite3 libffi-dev libssl-dev curl mplayer && \
apt-get -y install \
build-essential \
curl \
ffmpeg \
git-core \
libffi-dev \
libssl-dev \
mplayer \
net-tools \
procps \
python-dev \
python-imaging \
python-netifaces \
python-simplejson \
sqlite3 \
&& \
apt-get clean

# Install Python requirements
Expand Down
71 changes: 71 additions & 0 deletions Dockerfile.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
FROM resin/%%RESIN_MACHINE_NAME%%-debian
MAINTAINER Anton Molodykh <[email protected]>

RUN apt-get update && \
apt-get -y install \
build-essential \
curl \
git-core \
libffi-dev \
libssl-dev \
matchbox \
net-tools \
nginx-light \
omxplayer \
psmisc \
python-dev \
python-imaging \
python-netifaces \
python-simplejson \
sqlite3 \
uzbl \
x11-xserver-utils \
xserver-xorg && \
apt-get clean

RUN rm /etc/nginx/sites-enabled/default
COPY ansible/roles/ssl/files/nginx_resin.conf /etc/nginx/sites-enabled/screenly.conf

# Install Python requirements
ADD requirements.txt /tmp/requirements.txt
RUN curl -s https://bootstrap.pypa.io/get-pip.py | python && \
pip install --upgrade -r /tmp/requirements.txt

# Screenly Websocker Server
COPY ansible/roles/screenly/files/screenly-websocket_server_layer.service /etc/systemd/system/screenly-websocket_server_layer.service
RUN sed -i '/\[Service\]/ a\Environment=HOME=/data' /etc/systemd/system/screenly-websocket_server_layer.service

# Screenly Server
COPY ansible/roles/screenly/files/screenly-web.service /etc/systemd/system/screenly-web.service
RUN sed -i '/\[Service\]/ a\Environment=HOME=/data' /etc/systemd/system/screenly-web.service

# X11
COPY ansible/roles/screenly/files/X.service /etc/systemd/system/X.service

# Matchbox
COPY ansible/roles/screenly/files/matchbox.service /etc/systemd/system/matchbox.service

#Screenly Viewer
COPY ansible/roles/screenly/files/screenly-viewer.service /etc/systemd/system/screenly-viewer.service
RUN sed -i '/\[Service\]/ a\Environment=HOME=/data' /etc/systemd/system/screenly-viewer.service
RUN sed -i '/\[Service\]/ a\Environment=DISABLE_UPDATE_CHECK=True' /etc/systemd/system/screenly-viewer.service

# Enable container init system.
ENV INITSYSTEM on

# Create runtime user
RUN useradd pi -d /home/pi \
&& /usr/sbin/usermod -a -G video pi

# Install config file and file structure
RUN mkdir -p /home/pi/screenly
COPY ansible/roles/screenly/files/gtkrc-2.0 /home/pi/.gtkrc-2.0

# Copy in code base
COPY . /home/pi/screenly

RUN chown -R pi:pi /home/pi

WORKDIR /home/pi/screenly

CMD ["bash", "bin/start_resin.sh"]
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# Screenly OSE - Digital Signage for the Raspberry Pi

The tl;dr for installing Screenly OSE on [Raspbian](https://www.raspberrypi.org/downloads/raspbian/) Jessie is:
The tl;dr for installing Screenly OSE on [Raspbian Lite](https://www.raspberrypi.org/downloads/raspbian/) is:

```
$ bash <(curl -sL https://www.screenly.io/install-ose.sh)
Expand Down
33 changes: 33 additions & 0 deletions ansible/roles/ssl/files/nginx_resin.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
upstream ose {
server 127.0.0.1:8080;
}

upstream websocket {
server 127.0.0.1:9999;
}

server {
server_tokens off;
listen 80 default_server;

location / {
client_max_body_size 4G;
proxy_pass http://ose;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Protocol https;
}

location /ws/ {
proxy_pass http://websocket;
proxy_read_timeout 24d;
chunked_transfer_encoding off;
proxy_http_version 1.1;
proxy_buffering off;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $http_host;
}
}
40 changes: 40 additions & 0 deletions bin/start_resin.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/bin/bash

chown -R pi:pi /data

mkdir -p \
/data/.config \
/data/.config/uzbl \
/data/.screenly \
/data/screenly \
/data/screenly_assets

cp -n ansible/roles/screenly/files/screenly.conf /data/.screenly/screenly.conf
cp -n ansible/roles/screenly/files/screenly.db /data/.screenly/screenly.db
cp -n loading.png /data/screenly/loading.png
cp -n ansible/roles/screenly/files/uzbl-config /data/.config/uzbl/config-screenly

if [ -n "${OVERWRITE_CONFIG}" ]; then
echo "Requested to overwrite Screenly config file."
cp ansible/roles/screenly/files/screenly.conf "/data/.screenly/screenly.conf"
fi

# Set management page's user and password from environment variables,
# but only if both of them are provided. Can have empty values provided.
if [ -n "${MANAGEMENT_USER+x}" ] && [ -n "${MANAGEMENT_PASSWORD+x}" ]; then
sed -i -e "s/^user=.*/user=${MANAGEMENT_USER}/" -e "s/^password=.*/password=${MANAGEMENT_PASSWORD}/" /data/.screenly/screenly.conf
fi

sed -i "/\[Service\]/ a\Environment=RESIN_UUID=${RESIN_DEVICE_UUID}" /etc/systemd/system/screenly-web.service

systemctl start X.service
systemctl start matchbox.service
systemctl start screenly-viewer.service
systemctl start screenly-web.service
systemctl start screenly-websocket_server_layer.service

journalctl -f -a

# By default docker gives us 64MB of shared memory size but to display heavy
# pages we need more.
umount /dev/shm && mount -t tmpfs shm /dev/shm
34 changes: 34 additions & 0 deletions docs/resin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Install Screenly OSE using Resin.io

## tl;dr instructions

* Create a [Resin.io](https://www.resin.io) account
* [Create application](https://docs.resin.io/raspberrypi3/nodejs/getting-started/#create-an-application)
* Download resinOS
* Flash out the disk image
* Boot the device
* Clone the Screenly OSE repository:

```
$ git clone https://github.com/Screenly/screenly-ose.git
```

* Add the Resin git remote endpoint:

```
$ git remote add resin <USERNAME>@git.resin.io:<USERNAME>/<APPNAME>.git
```

* Push the code to Resin.io:

```
$ git push resin master
```

*(This will take some time, as all components are being installed)*

* Navigate to "Fleet Configuration" in the web interface and create a new configuration with the key `RESIN_HOST_CONFIG_gpu_mem` and the value `64`. If you're having issues with video playback performance, you may need to increase this to 192, or sometimes even 256.

## Longer instructions

For more detailed instructions, including a screencast, check out the blog post [Deploy a digital signage application with Screenly OSE and resin.io](https://resin.io/blog/deploy-a-digital-signage-application-with-screenly-and-resin/).
49 changes: 22 additions & 27 deletions lib/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
# This will work on x86-based machines
if machine() in ['x86', 'x86_64']:
try:
from sh import mplayer
from sh import ffprobe, mplayer
except:
pass

Expand All @@ -56,8 +56,7 @@ def validate_url(string):


def get_node_ip():
if arch in ('armv6l', 'armv7l'):

if arch in ('armv6l', 'armv7l') and getenv("RESIN_UUID") is None:
interface = None
for n in range(10):
iface = 'eth{}'.format(n)
Expand Down Expand Up @@ -92,7 +91,6 @@ def get_node_ip():
"""Returns the node's IP, for the interface
that is being used as the default gateway.
This shuld work on both MacOS X and Linux."""

try:
default_interface = grep(netstat('-nr'), '-e', '^default', '-e' '^0.0.0.0').split()[-1]
my_ip = ifaddresses(default_interface)[2][0]['addr']
Expand All @@ -106,28 +104,23 @@ def get_video_duration(file):
Returns the duration of a video file in timedelta.
"""
time = None
try:
if arch in ('armv6l', 'armv7l'):
run_omxplayer = omxplayer(file, info=True, _err_to_out=True)
for line in run_omxplayer.split('\n'):
if 'Duration' in line:
match = re.search(r'[0-9]+:[0-9]+:[0-9]+\.[0-9]+', line)
if match:
time_input = match.group()
time_split = time_input.split(':')
hours = int(time_split[0])
minutes = int(time_split[1])
seconds = float(time_split[2])
time = timedelta(hours=hours, minutes=minutes, seconds=seconds)
break
else:
run_mplayer = mplayer('-identify', '-frames', '0', '-nosound', file)
for line in run_mplayer.split('\n'):
if 'ID_LENGTH=' in line:
time = timedelta(seconds=int(round(float(line.split('=')[1]))))
break
except:
pass

if arch in ('armv6l', 'armv7l'):
run_player = omxplayer(file, info=True, _err_to_out=True, _ok_code=[0, 1])
else:
run_player = ffprobe('-i', file, _err_to_out=True)

for line in run_player.split('\n'):
if 'Duration' in line:
match = re.search(r'[0-9]+:[0-9]+:[0-9]+\.[0-9]+', line)
if match:
time_input = match.group()
time_split = time_input.split(':')
hours = int(time_split[0])
minutes = int(time_split[1])
seconds = float(time_split[2])
time = timedelta(hours=hours, minutes=minutes, seconds=seconds)
break

return time

Expand Down Expand Up @@ -207,13 +200,15 @@ def url_fails(url):
def download_video_from_youtube(uri, asset_id):
home = getenv('HOME')
name = check_output(['youtube-dl', '-e', uri])
info = json.loads(check_output(['youtube-dl', '-j', uri]))
duration = info['duration']

location = path.join(home, 'screenly_assets', asset_id)
thread = YoutubeDownloadThread(location, uri, asset_id)
thread.daemon = True
thread.start()

return location, unicode(name.decode('utf-8'))
return location, unicode(name.decode('utf-8')), duration


class YoutubeDownloadThread(Thread):
Expand Down
Loading

0 comments on commit 7bef424

Please sign in to comment.