how to check if the airplay is being used? - audio

I'm trying to cast music on TV through airplay using MPMusicPlayerController. How can I check if the airplay is being used by other inputs?

Couple of existing posts which may be of use:
Is there any notification for detecting AirPlay in Objective-C?
How to customize the Airplay button when airplay is active
There is a post in the second link that defines the method - (BOOL)isAirPlayActive which neatly uses the AudioSession framework to determine the current audio output route.

Here is another solution to detect whether airplay is active
- (BOOL)isAirPlayActive
{
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
AVAudioSessionRouteDescription* currentRoute = audioSession.currentRoute;
AVAudioSessionPortDescription* output = [currentRoute.outputs firstObject];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
return [output.portType isEqualToString:AVAudioSessionPortAirPlay];
}

I had this problem as well, and I ended up using arp -n to get the mac address of the airplay device and then used tcpdump to sniff traffic to it:
ipaddress=$(ping -c 1 $tvhostname | awk -F'[()]' '/PING/{print $2}')
arp -n $ipaddress &> /var/tmp/arp-output
fieldindex='$4'
# Parse something of the form ? (10.37.109.150) at 40:33:1a:3d:e6:ee on en0 ifscope [ethernet]
# The awk quotes get a bit messy with the variable substitution, so split the expression up
echo Parsing mac address from line `awk -F"[ ]" "/\($ipaddress\)/{print}" /var/tmp/arp-output`
macaddress=`awk -F"[ ]" "/($ipaddress)/{print $fieldindex}" /var/tmp/arp-output`
sudo tcpdump -i $wifidevice -I ether dst $macaddress &> /var/tmp/airplay-tcpdump-output
# Get the PID of the tcpdump command
pid=$!
# Capture 10 seconds of output, then kill the job
sleep 10
sudo kill $pid
# Process the output file to see how many packets are reported captured
packetcount=`awk -F'[ ]' '/captured/{print $1}' /var/tmp/airplay-tcpdump-output`
echo Finished sniffing packets - there were $packetcount.
The full script ended up being a bit involved, so I wrote it up in a blog post.

Related

How can I tail dmesg

I am using Ubuntu 20.04.3 LTS. I am trying to monitor the serial port connect with my Arduino.
I have seen my friend using the following command (he performed it in my laptop):
tail -f {dmesg,syslog} | grep -i tty
And whenever I plugin and unplug the arduino, the terminal always keep up showing serial port name, its condition. But when I try it myself, it says that there is not such file or directory. I have search and tried following command:
tail -f var/log/dmesg
tail -f var/log/{dmesg,syslog}
But it seems like it does not show up the serial port or keep up with condition. Would you help me with any ideas?
You can use
dmesg -W | grep -i tty
-w, --follow
Wait for new messages. This feature is supported only on systems with a readable /dev/kmsg (since kernel 3.5.0).
So Output will be something like this
rexter#rexter:/media/rexter/REXDRIVE$ dmesg -w | grep -i tty
[ 0.112876] printk: console [tty0] enabled
[ 332.500320] Bluetooth: RFCOMM TTY layer initialized
If you want to get only new message and want to hide the old ones then use -W
-W, --follow-new
Wait and print only new messages.
Bonus:
Use -T to get the time stamp so that you can get the time when you receive the log.
Thank you :)

Detect IP-Address change on an interface

I would like to trigger a service when a change of an ip address on a specific interface occurs. Is there a target for this or some other method I am not aware of to achieve this using systemd on Linux (Kernel 3.19)?
The service would be used to send a SIGNAL to a defined process. The Linux is running on an embedded system.
Thanks!
Because you use Systemd you might already use systemd-networkd for managing your devices instead of relying on 3rd party code.
You could use the structured journal output to get the last 2 ADDRESS field of the current BOOD_ID.(sadly, there is no notification mechanism for address changes in systemd-networkd):
→ sudo journalctl -F ADDRESS -u systemd-networkd -n 2
192.168.178.29
So, if there is only one line output, there was no address change.
There is an solution in other question of StackOverflow. Just here:
Detecting a change of IP address in Linux
I like this code, it's easy, you onli need a cron job with frecuency as you need (I made a little change):
#!/bin/bash
OLD_IP=`cat ip.txt`
NEW_IP=`/sbin/ifconfig | awk -F "[: ]+'{ print $4}'`
if [ $NEW_IP != OLD_IP ]; then
YOU_COMMAND <commands>
echo $NEW_IP > ip.txt
fi
exit 0

How can I have tcpdump write to file and standard output the appropriate data?

I want to have tcpdump write raw packet data into a file and also display packet analysis into standard output as the packets are captured (by analysis I mean the lines it displays normally when -w is missing).
Can anybody please tell me how to do that?
Here's a neat way to do what you want:
tcpdump -w - -U | tee somefile | tcpdump -r -
What it does:
-w - tells tcpdump to write binary data to stdout
-U tells tcpdump to write each packet to stdout as it is received, rather than buffering them and outputting in chunks
tee writes that binary data to a file AND to its own stdout
-r - tells the second tcpdump to get its data from its stdin
Since tcpdump 4.9.3 4.99.0, the --print option can be used:
tcpdump -w somefile --print
Wednesday, December 30, 2020, by mcr#sandelman.ca, denis and fxl.
Summary for 4.99.0 tcpdump release
[...]
User interface:
[...]
Add --print, to cause packet printing even with -w.
tcpdump ${ARGS} &
PID=$!
tcpdump ${ARGS} -w ${filename}
kill $PID
If you want a way to do it without running tcpdump twice, consider:
sudo tcpdump port 80 -w $(tty) | tee /tmp/output.txt
From the interactive command prompt you could use $TTY instead of $(tty) but in a script the former wouldn't be set (though I'm not sure how common it is to run tcpdump in a script).
Side-note: it's not very Unix-y the way tcpdump by default makes you write to a file. Programs should by default write to stdout. Redirection to a file is already provided by the shell constructs. Maybe there's a good reason tcpdump is designed this way but I don't know what that is.

Executing a tcpstat command and performing operations on its output simultaneously

I am trying to run a tcpstat command that gives the output about number of icmp requests being received. and at the same time i need to check the count so that if it exceeds some threshold, a message should be displayed.
i tried out something like this
#!/usr/bin/perl
my #count= system "tcpstat -i eth1 -f icmp[0]==8 -o %C";
my $i=0;
while ($i<1000)
{
print "count of packets is :".$count[$i]."\n";
$i=$i+1;
if($count[$i]>50)
{
print "thats a lot of pings";
}
}
but it doesn't seem to work because.. the execution of the command doesn't end without an user interrupt...
is it possible to do that? running the command and simultaneously performing operations over its output?
Run your tcpstat command in shell and pipe the output to your perl script.
tcpstat -i eth1 -f icmp[0]==8 -o %C | perl script.pl
In this way, you should expect your input from <STDIN> and remove the system call in perl, of course.

Linux Shell: VLC programming

Is there a way to manipulate VLC with a Linux shell script without the script waiting for VLC to close.
cvlc test.mp3
echo "Now playing!"
sleep 200
cvlc://pause:60
This code keeps running VLC until the file is completed, and then evidently it is to late to pause the file.
You need to use dbus interface of VLC.
Now, you can use the mpris interface of VLC. It's a standard for most players like clementine, banshee, songbird, spotify etc.
So, lets suppose you want to Pause the currently playing song.
dbus-send --print-reply --session --dest=org.mpris.vlc /Player org.freedesktop.MediaPlayer.Pause
To play a song:
dbus-send --print-reply --session --dest=org.mpris.vlc /Player org.freedesktop.MediaPlayer.Play
I generally use qdbusviewer to know about the dbus-interface available to me.
Dbus is one way but dbus does not exist on all systems. The more common method would be to use the rc interface:
cvlc -I rc --rc-host localhost:11337 -d
Then one can use netcat to pipe commands into the tcp socket. For example:
vlc -I rc --rc-host localhost:11337 test.mp3 -d &
echo "Now playing!"
sleep 200
echo pause | netcat localhost 11337
EDIT:
After testing with a few other interfaces I have discovered the oldrc interface accepts UNIX domain sockets thus the following will work as well with out needing to play around with firewalls or worry about anyone else on the network messing around with your vlc instance.
vlc -I oldrc --rc-unix /var/run/vlc.sock -d
echo "Now Playing!"
sleep 200
echo "pause" | netcat -U /var/run/vlc.sock
It looks like you can redirect from standard input or a named pipe. For more complicated things you could use libvlc.
http://wiki.videolan.org/Uncommon_uses

Resources