Filed under Technology

Using obsidian-remote

Recently, I discovered a new way to use obsidian in a VNC session and it has been a game changer for me. I know, I know, you might be thinking, "Why would I want to do that?" Well, let me tell you, the answer is simple - because it's awesome!

Let me give you a little background on how I stumbled upon this amazing discovery. As a #homelab enthusiast, I am always looking for ways to optimize my workflow and make things easier for myself. One of my latest projects was to sync my obsidian vault to a headless server. For those of you who are not familiar, a headless server is a computer without a monitor, keyboard, or mouse, and is usually controlled remotely.

Now, I am currently using Synology for my homelab and I didn't want to rely on another computer to sync my obsidian vault with it. That's when the idea struck me - why not run obsidian in a VNC session on my Synology? And let me tell you, it was a brilliant idea.

For those who are not familiar, VNC (Virtual Network Computing) is a graphical desktop sharing system that allows you to remotely control another computer. And the best part is, I could connect to my Synology over the web through Tailscale, making it even more convenient. If you don’t know what Tailscale is, oh boy, you are in for a treat. You can go check it out. I give you permission. ;-)

So, I did a little research and came across the obsidian-remote repo on GitHub. I made a few modifications to the files and voila, I was able to run obsidian in a VNC session on my Synology. It was like a dream come true for me. Now, I can access my obsidian vault from anywhere, anytime, without having to rely on another computer.

I am sure some of you might be wondering, "But how does this benefit me?" Well, let me tell you, the possibilities are endless. Whether you are a student, a writer, a researcher, or just someone who loves to organize their thoughts, obsidian in a VNC session can make your life so much easier. You can access your vault from any device, as long as you have an internet connection. No more worrying about forgetting important notes or files on a different computer. Obsidian Sync also provides version history for a year, allowing you to revert to previous versions of notes at any time. I should mention that I am not exposing any ports on the internet. Everything is through Tailscale. I'm using their free tier as a solo #homelab enthusiast.

Enough of the chit-chat, here is what I did. I modified a few files from the obsidian-remote repo.

git clone https://github.com/sytone/obsidian-remote

I changed the Dockerfile.

FROM ghcr.io/linuxserver/baseimage-kasmvnc:debianbookworm

# Update and install extra packages.
RUN echo "**** install packages ****" && \
    apt-get update && \
    apt-get install -y --no-install-recommends curl libgtk-3-0 libnotify4 libatspi2.0-0 libsecret-1-0 libnss3 desktop-file-utils fonts-noto-color-emoji git ssh-askpass && \
    apt-get autoclean && rm -rf /var/lib/apt/lists/* /var/tmp/* /tmp/*

# Set version label
ARG OBSIDIAN_VERSION=1.5.11

# Download and install Obsidian
RUN echo "**** download obsidian ****" && \
    curl --location --output obsidian.deb "https://github.com/obsidianmd/obsidian-releases/releases/download/v${OBSIDIAN_VERSION}/obsidian_${OBSIDIAN_VERSION}_amd64.deb" && \
    dpkg -i obsidian.deb

# Environment variables
ENV CUSTOM_PORT="8083" \
    CUSTOM_HTTPS_PORT="8443" \
    CUSTOM_USER="" \
    PASSWORD="" \
    SUBFOLDER="" \
    TITLE="Obsidian v${OBSIDIAN_VERSION}" \
    FM_HOME="/vaults"

# Add local files
COPY root/ /
EXPOSE 8083 8443
VOLUME ["/config","/vaults"]

# Define a healthcheck
HEALTHCHECK CMD curl --fail http://localhost:8083/ || exit 1

I also changed a few files in the /root directory to remove sudo in the menu.xml and autostart file. You might want to check your config folder in your docker-compose.yml to see it stuck. I did this a couple times. I remove one line in the startwm.sh that started a script called pulseaudio. I don’t need that so I didn’t really care. I could probably connect the audio to a machine but that’s not my use case.

I proceed to build it with the usual docker build . -t obsidian-remote. After building the container, I modified the docker-compose.yml to suit my need and came up with this one.

services:
  obsidian:
#    image: 'ghcr.io/sytone/obsidian-remote:latest'
    image: obsidian-remote:latest
    container_name: obsidian-remote
    restart: unless-stopped
    healthcheck:
      test: curl -f http://localhost:8080/ || exit 1
    ports:
      - 8083:8083
      - 8443:8443
    volumes:
      - /my/homes/vault:/vaults
      - ./config:/config
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/Montreal
      - DOCKER_MODS=linuxserver/mods:universal-git
      - CUSTOM_PORT=8083
      - CUSTOM_HTTPS_PORT=8443
      - CUSTOM_USER=
      - PASSWORD=
      - SUBFOLDER

Everything seems to be working. I sync my vault to my Synology using Obsidian sync which I pay for. Pretty happy to be able to do this.

Find me on @benoitb@mas.to mastodon if you have any questions.

Fixing Crackling Sound Issue with AlsaMixer

To fix the crackling sound issue with muting and unmuting the sound, you can follow these steps:

  1. Open the terminal and enter the command alsamixer to launch the AlsaMixer interface.
  2. Use the F6 key to select the default sound card.
  3. Use the arrow keys to navigate to the S/PDIF option.
  4. Press the 'M' key to mute the S/PDIF option.
  5. Press the 'M' key again to unmute the S/PDIF option.

By muting and unmuting the S/PDIF option, you can potentially resolve the crackling sound issue. This method has worked for some users who experienced similar problems.

If you are using a dock with a keyboard, mouse, and external monitor attached, this solution might work for you as well. Give it a try and let me know how it goes!

Please note that these instructions are specific to AlsaMixer and may not apply to other sound control applications.

I hope this helps!

My updated music setup

I've updated how I use part of my music system at home from the previous example here. I took inspiration from the following mopidy issue at GitHub.The big difference in how I've set it up before is that mopidy now use the audio output and send it to a UDP sink with the following tibits.

[audio]
output = tee name=t ! queue ! autoaudiosink t. ! queue ! udpsink host=127.0.0.1 port=5555

I then use socat to make it a fifo so that forked-daapd can stream it wherever I want. Here is the script that I use to launch it during boot.

#!/bin/bash

createFifo() {
fifo='/srv/music/mopidy.fifo' # this is where my forked-daapd will read it
rm $fifo

mkfifo "$fifo"
while :; do socat -d -d -T 1 -u UDP4-LISTEN:5555 OPEN:"$fifo"; done
}

var=`ps -C socat -F | grep [s]ocat | tr -s " " | cut -d " " -f2`
if [ -z "$var" ]; then
 createFifo
fi

Here is the breakdown of what's happening in the previous script. I create a simple bash function to make the fifo and make sure to only run it if no other instance of socat is running. If you have another instance of socat running you probably just need to kill that particular instance if it's not working.

I also created a simple systemd service file to load it up at boot time which I put in /etc/systemd/system/

[Unit]
Description=Startup mopidy udplink to fifo

[Service]
Type=oneshot
ExecStart=/etc/mopidy/startup.sh

[Install]
WantedBy=multi-user.target

Reload udev rules without rebooting

A simple way to reload udev rules and trigger the new rules all wrap into a oneliner.

$ udevadm control --reload-rules && udevadm trigger

Using Linux Tools To Send To DayOne App

Ive started getting back into journaling with DayOne recently. The reason why I like using DayOne is supper simple. It's a great interface. The sync features is great. It works with IFTTT. It great with photo journaling. It has a bunch of workflow goodness on the iOS platform using workflow.app and launch center pro. The problem I do have is that I spend quite a bit of time using my Debian box. I hope my information is secured in the clouds within DayOne biosphere. In short I love being able to use the app on my iOS devices. One thing that was bothering me a bit was that I wanted to be able to use it on my computer which like I said its running Debian. I stumbled awhile ago jrnl. Its a great way to keep a journal using the command line which is where I like to live. I wanted to send my journal entries to DayOne from jrnl which is super easy. On this computer I also setup mutt with my gmail account. The glue between jrnl and DayOne is ifttt.com. I have a recipe that when I send an email to trigger@recipe.ifttt.com it forwards it to my DayOne journal. The recipe in question is this one applets.

$ jrnl "Hey look, im using the command line to send to DayOne" $ jrnl -n 1 | mutt -s "command line awesomeness" trigger@recipe.ifttt.com

How cool is that? Maybe I can also send my DayOne entry to jrnl.

My music setup at home with mopidy, forked-daapd and shairport-sync

UPDATE 1: I've modified a bit of a section from this here.

Here is my music setup at home. I have a mac mini that's been transformed to a server running debian stretch. It runs a few deamons. I have mopidy as my main web interface which is also connected to Spotify and Soundcloud through mopidy plugins. What is mopidy? Taken from their github site 'Mopidy is an extensible music server that plays music from local disk, Spotify, SoundCloud, Google Play Music, and more.' The backend is forked-daapd which is a Linux/FreeBSD DAAP (iTunes) with support for AirPlay devices (multiroom). Mopidy connects to forked-daapd that then streams to any AirPlay devices to multiple rooms in my house. Im pretty happy with this setup but I wanted more. I wanted to be able to use my iDevices or having my spouse or kids to be able to steam to our multiroom setup. That's when shairport-sync comes in. I can pipe the music stream to forked-daapd that send audio to all AirPlay devices and not only that but also the metadata from the shairport-sync.

I know you could do with something like Rogue Amoeba Airfoil but then you need your mac to be on at all time which I didnt want to do. Part of the reason that I installed linux on the mini is also because I run Kodi on it. It runs these daemons and kodi. I didnt want the bloat of running macOS just for that.

Here is the kicker with this setup, I could put speakers anywhere either inside or outside the house thats connected to the network and play music from any devices to them. Putting speakers outside is on my to-do list which seems to be getting longer and longer. Ohh the joy of owning a house in Upstate NY. But in any case I digress, it's super easy to transform a raspberrypi into an audio hub with shairport-sync. The quality of the audio isnt that great on the first generation of raspberrypi devices but seem to be fairly decent on newer 2+ models. Dont quote me on this.

Here are the steps I've used.

mopidy

To download mopidy you should follow the instructions on this page https://docs.mopidy.com/en/latest/installation/. For my debian box, here is what I did.

I added the mopidy GPG key:

$ wget -q -O - https://apt.mopidy.com/mopidy.gpg | sudo apt-key add -

Added the APT repo to your package sources:

$ sudo wget -q -O /etc/apt/sources.list.d/mopidy.list https://apt.mopidy.com/stretch.list

Install Mopidy and all dependencies:

$ sudo apt-get update
$ sudo apt-get install mopidy

You can search for every extensions on the repository with the search command which is very useful. For example, installing extensions spotify and soundcloud.

$ apt search mopidy
$ sudo apt install mopidy-spotify mopidy-soundcloud

mopidy config files

If you have a local music library then make sure you point it to the right directory. Here is my config file located in /etc/mopidy/mopidy.conf. You should check out https://docs.mopidy.com/en/latest/config/ to fully understand all the possibilities. I disabled MPD because I didnt need it. You should replace $USER with your actual home folder.

[core]
cache_dir = /var/cache/mopidy
config_dir = /etc/mopidy
data_dir = /var/lib/mopidy

[logging]
config_file = /etc/mopidy/logging.conf

[audio]
output = audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! filesink
location=/home/$USER/music/mopidy

[mpd]
enabled = false

[http]
enabled = true
hostname = 0.0.0.0
port = 6680
zeroconf = Mopidy HTTP server on $hostname

[softwaremixer]
enabled = true

[local]
enabled = true
library = json
media_dir = /home/$USER/music
scan_timeout = 1000
scan_flush_threshold = 100
excluded_file_extensions =
.directory
.html
.jpeg
.jpg
.log
.nfo
.png
.txt

[spotify]
enabled = true
username = alice
password = secret
bitrate = 320
client_id = client_id value you got from mopidy.com
client_secret = client_secret value you got from mopidy.com

[scrobbler]
username = alice
password = secret

[soundcloud]
auth_token = 1-1111-1111111

mopidy-spotify

For more information on the mopidy-spotify plugins check out https://github.com/mopidy/mopidy-spotify. What I had to do to be able to fun spotify was to modify the config files /etc/mopidy/mopidy.conf. You will need to find your spotify username and password that are located in your account overview page at https://www.spotify.com/us/account/overview/ and put it instead of the ones below. After you put your info in the conf files you will need to visit https://www.mopidy.com/authenticate/#spotify to authorize this extension against your Spotify account:

[spotify]
username = alice
password = secret
client_id = client_id value you got from mopidy.com
client_secret = client_secret value you got from mopidy.com

mopidy-soundcloud

To configure mopidy-soundcloud located https://github.com/mopidy/mopidy-soundcloud you need to follow the following steps stated on the website:

  1. You must register for a user account at http://www.soundcloud.com/
  2. You need a SoundCloud authentication token for Mopidy from http://www.mopidy.com/authenticate
  3. Add the authentication token to the mopidy.conf config file:
[soundcloud]
auth_token = 1-1111-1111111
explore_songs = 25

mopidy running as a service

Systemd ways of running services is fairly easy. You should enable it using:

$ sudo systemctl enable mopidy

Now that this is enabled, it will start mopidy after each boot.

To start, stop and restart you use the following command:

$ sudo systemctl start mopidy
$ sudo systemctl stop mopidy
$ sudo systemctl restart mopidy

You can check the status of the service with:

$ sudo systemctl status mopidy

mopidy web extensions

We will need a web interface to be the front end of mopidy. My two favorite are Mopidy-MusicBox-Webclient and Mopidy-Mopify both available with pip. Mopify is great for spotify access and musicbox is great for iDevices.

$ sudo pip install Mopidy-Mopify
$ sudo pip install Mopidy-MusicBox-Webclient

Now that its installed you should go to the URL 0.0.0.0:6680 to see if it worked.

forked-daapd

Here are the step that I use to install forked-daapd.

$ sudo apt-get install build-essential git autotools-dev autoconf libtool gettext gawk gperf antlr3 libantlr3c-dev libconfuse-dev libunistring-dev libsqlite3-dev libavcodec-dev libavformat-dev libavfilter-dev libswscale-dev libavutil-dev libasound2-dev libmxml-dev libgcrypt11-dev libavahi-client-dev zlib1g-dev libevent-dev libplist-dev libsodium-dev libjson-c-dev libwebsockets-dev

Optional packages:

Feature Configure argument Packages
Chromecast --enable-chromecast libgnutls-dev libprotobuf-c-dev
LastFM --enable-lastfm libcurl4-gnutls-dev OR libcurl4-openssl-dev
iTunes XML --disable-itunes libplist-dev
Device verification --disable-verification libplist-dev libsodium-dev
Live web UI --with-libwebsockets libwebsockets-dev
Pulseaudio --with-pulseaudio libpulse-dev
$ git clone https://github.com/ejurgensen/forked-daapd.git
$ cd forked-daapd
$ autoreconf -i
$ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --with-pulseaudio --enable-lastfm
$ make
$ sudo make install

Now that it's installed check the config file /etc/forked-daapd.conf and make sure you have your music directory in the config file like below.

# Directories to index
directories = { "/home/$USER/music" }

and to stream the music from other devices via the pipe that we will create later we need to make sure it set to true. Let's adjust one more thing in the config file.

# Watch named pipes in the library for data and autostart playback when
# there is data to be read. To exclude specific pipes from watching,
# consider using the above _ignore options.
pipe_autostart = true

I disabled a bunch of other options because I didnt need them like MPD, spotify and such.

forked-daapd running as a service

Done with config file, lets move to have it run it as a service. Here is my forked-daapd.service file located in my /etc/systemd/system folder. I use the following options are

  • Running in the foreground with -f
  • Debug log level -d 0
  • Location of the config file with -c /etc/forked-daapd.conf
[Unit]
Description=DAAP/DACP (iTunes), RSP and MPD server, supports AirPlay and Remote
Documentation=man:forked-daapd(8)
After=network.target sound.target remote-fs.target pulseaudio.service avahi-daemon.service

[Service]
ExecStart=/usr/sbin/forked-daapd -f -d 0 -c /etc/forked-daapd.conf

# Restart, but not more than once every 10 minutes
Restart=on-failure
StartLimitBurst=2
StartLimitInterval=600

[Install]
WantedBy=multi-user.target

Like mopidy and any other systemd services, to enable forked-daapd to run here is what I do.

$ sudo systemctl enable forked-daapd

Now that this is enabled, it will start forked-daapd after each boot.

To start, stop and restart you use the following command:

$ sudo systemctl start forked-daapd
$ sudo systemctl stop forked-daapd
$ sudo systemctl restart forked-daapd

You can check the status of the service with:

$ sudo systemctl status forked-daapd

If it's running you should be able to go to http://[your_server_address_here]:3689 and see your current AirPlay devices. You will be able to toggle them on or off.

Shairport-sync

Now, here is where the magic will happen, creating a pipe. Make sure you have the right permissions meaning that $USER can read/write to the music folder. Maybe perharps a chmod -R 755 music. Lets also restart forked-daapd.

$ mkfifo /home/$USER/music/shairport
$ mkfifo /home/$USER/music/shairport.metadata
$ chmod 777 shairport shairport.metadata
$ sudo systemctl restart forked-daapd

Now that we have forked-daapd running we need to start installing shairport-sync in order to have other user or devices able to stream to the AirPlay devices.

sudo apt install build-essential git xmltoman autoconf automake libtool libdaemon-dev libpopt-dev libconfig-dev libasound2-dev libpulse-dev avahi-daemon libavahi-client-dev libsoxr-dev

Let's download shairport-sync and build it. I used the following settings for building shairport-sync. Do check the README.md file for more information about each settings. It has tons of information. I also run shairport-sync on a raspberrypi

$ git clone https://github.com/mikebrady/shairport-sync.git
$ cd shairport-sync
$ autoreconf -i -f
$ ./configure --sysconfdir=/etc --with-alsa --with-pa --with-avahi --with-ssl=openssl --with-metadata --with-soxr --with-systemd
$ make -j4
$ sudo make install

My shairport-sync.conf file in /etc

general = {
  name = "SHAIRPORT";
  output_backend = "pipe";
};

metadata = {
  enabled = "yes";
  include_cover_art = "yes";
  pipe_name = "/home/$USER/music/shairport.metadata";
}

sessioncontrol = {
  allow_session_interruption = "yes";
  session_timeout = 20;
}

pipe = {
  name = "/home/$USER/music/shairport";
  audio_backend_buffer_desired_length = 48000;
}

Now that you have the pipe set up you will be able to have music sent to all your speakers selecting the SHAIRPORT device. You should now make shairport-sync start at boot time. Lets use systemd again. It should have installed the file already in the /lib/systemd/system/shairport-sync.service folder and possibly created a shairport-sync user and group. Here is the conf file just in case.

[Unit]
Description=ShairportSync AirTunes receiver
After=sound.target
Requires=avahi-daemon.service
After=avahi-daemon.service
Wants=network-online.target
After=network.target network-online.target

[Service]
ExecStart=/usr/local/bin/shairport-sync
User=shairport-sync
Group=shairport-sync

[Install]
WantedBy=multi-user.target

Let's make sure it will run after each reboot enabling it in systemd and then let's restart it.

$ sudo systemctl enable shairport-sync.service
$ sudo systemctl restart shairport-sync.service

In any of the systemd services conf file above either for mopidy, forked-daapd or shairport-sync you should make sure if it's running. Troubleshooting various issues like permissions, wrong ExecStart configuration would be where I would start if you run into trouble.

Now you should be able to stream either via mopidy using the web interface within the URL 0.0.0.0:6680 to your AirPlay speakers or you could also use your iDevices/laptop to stream to all your AirPlay speakers. Ive been running this setup for quite some time and its rocking the house. I should also mention that it does have a 4-5 sec latency issue but I dont mind since its only for our listening pleasure. No mixing involve yet..