octombrie 2020 laboratorul 1. streaming audio folosind

24
ISSA – Laboratorul 1 Octombrie 2020 Laboratorul 1. Streaming audio folosind Bluetooth Laborator ora 16:00 – 18:00 : join teams room Join Microsoft Teams Meeting Laborator ora 18:00 – 20:00: join teams room Join Microsoft Teams Meeting Aplicatiile practice pe care le vom dezvolta in primele trei laboratoare contin principii care sunt la baza solutiilor dezvoltate de inginerii Continental din cadrul departamentului Vehicle Networking and Information. Ne propunem sa contruim un dispozitiv embedded care sa simuleze functiile de baza care se regasesc in cadrul unui sistem de in-car-infotainment. Pe masura ce sistemul nostru va prinde contur, il vom dezvolta prin adaugarea unor functionalitati din aria de Telematica. Suportul hardware pe care il vom folosi este o placa de dezvoltare Raspberry Pi. Din cauza contextului nefavorabil ce determina sustinerea de la distanta a laboratorului, accesul studentilor la dispozitive nu va fi posibil. De aceea, in prima parte a laboratorului, vom configura un dispozitiv virtual care sa inlocuiasca placa de dezvoltare. Tema 1: Instalare masina virtuala cu system de operare Raspbian - 2 pct Descarcati VirtualBox de la link-ul: https://www.virtualbox.org/wiki/Downloads/ Descarcati imaginea de Raspberry Pi de la link-ul: https://www.raspberrypi.org/downloads/raspberry-pi-desktop/ Porniti installer-ul VirtualBox si apoi Click “Yes”.

Upload: others

Post on 28-Jan-2022

8 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

Laboratorul 1. Streaming audio folosind Bluetooth

Laborator ora 16:00 – 18:00 : join teams room Join Microsoft Teams Meeting

Laborator ora 18:00 – 20:00: join teams room Join Microsoft Teams Meeting

Aplicatiile practice pe care le vom dezvolta in primele trei laboratoare contin principii care sunt la baza

solutiilor dezvoltate de inginerii Continental din cadrul departamentului Vehicle Networking and

Information. Ne propunem sa contruim un dispozitiv embedded care sa simuleze functiile de baza care se

regasesc in cadrul unui sistem de in-car-infotainment. Pe masura ce sistemul nostru va prinde contur, il

vom dezvolta prin adaugarea unor functionalitati din aria de Telematica.

Suportul hardware pe care il vom folosi este o placa de dezvoltare Raspberry Pi. Din cauza contextului

nefavorabil ce determina sustinerea de la distanta a laboratorului, accesul studentilor la dispozitive nu va

fi posibil. De aceea, in prima parte a laboratorului, vom configura un dispozitiv virtual care sa inlocuiasca

placa de dezvoltare.

Tema 1: Instalare masina virtuala cu system de operare Rasp bian - 2 pct

Descarcati VirtualBox de la link-ul:

https://www.virtualbox.org/wiki/Downloads/

Descarcati imaginea de Raspberry Pi de la link-ul:

https://www.raspberrypi.org/downloads/raspberry-pi-desktop/

Porniti installer-ul VirtualBox si apoi Click “Yes”.

Page 2: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

In acest moment avem descarcata imaginea de Raspberry Pi Desktop si VirtualBox este instalat. Suntem

pregatiti pentru a crea masina virtuala. In interfata grafica a virtual box, apasati butonul “New”:

In fereastra nou aparuta, vom alege un nume potrivit pentru dispozitivul virtual, si vom selecta tipul Linux

si versiunea Debian(64-bit).

Page 3: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

In continuare vom selecta dimensiunea memoriei RAM ce dorim sa fie alocata pentru Raspbian.

Recomandarea este sa folosim dimensiunea recomandata de 1024 MB pentru a replica cat mai fidel

performantele unui dispozitiv Raspberry Pi, care are 1GB memorie RAM.

In continuare selectati optiunea “Create a virtual hard disk now”:

Page 4: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

In continuare vom selecta tipul de fisier folosit pentru noul disc virtual. Vom selecta optiunea VirtualBox

Disk Image:

In fereastra urmatoare vom selecta optinea de a folosi un disc de dimensiune fixa. In continuare vom seta

dimensiunea initiala a discului virtual. Vom alege o dimensiune de peste 16 GB, in ideea ca dispozitivul

Raspberry Pi ar fi dotat cu un SD card de aceasta capacitate.

Page 5: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

Vom apasa create si vom astepta pentru finalizarea procesului:

In acest moment dispozitivul nostru virtual este pregatit pentru instalarea imaginii de Raspbian. Vom face

dublu click pe el in meniul din Virtual Box ( selectia cu portocaliu din imaginea de mai jos).

Page 6: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

In continuare vom cauta calea catre imaginea de Raspbian descarcata la inceputul laboratorului:

Page 7: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

Vom selecta optiunea Install:

Page 8: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

Selectati keymap-ul dorit:

Page 9: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

Page 10: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

Page 11: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

Page 12: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

In acest moment desktop-ul Raspbian este pregatit pentru folosire .

Tema 2: Streaming audio folosing Bluetooth (A2DP) – 1 pct

Prima aplicatie practica pe care o vom realiza este sa folosim dispozitivul Raspberry Pi pentru

streaming audio prin conectarea prin Bluetooth la un telefon mobil. In acest scop vom folosi

profilul A2DP, care este dedicat streamingului audio folosind bluetooth.

Page 13: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

A2DP (Advanced Audio Distribution Profile) - Profilul avansat de distribuție audio (A2DP)

definește protocoalele și proceduri care realizează distribuția conținutului audio de înaltă calitate

în mono sau stereo pe canale ACL. Un scenariu tipic de utilizare este streaming-ul de conținut

muzical de la un player muzical stereo la căști sau difuzoare. Datele audio sunt comprimate într-

un format adecvat pentru utilizarea eficientă a lățimii de bandă limitată. Distribuția sunetului

surround nu este inclusă în domeniul de aplicare al acestui profil.(Advanced Audio Distribution

Profile - Bluetooth Specification)

HCI - Host Controller Interface -> standardizeaza comunicarea intre stack-ul implementat de host si

controler-ul bluetooth

L2CAP - Protocol bluetooth din cadrul bluetooth stack

-multiplexeaza datele venite de la protocoalele higher level

-segmenteaza si reasambleaza pachetele de date

-Quality of service management pentru protocoalele higher level

Link Manager/Controller - protocol ce gestioneaza detectarea device-urilor bluetooth apropiate si

realizarea conexiunii bluetooth

Audio/video control transport protocol (AVCTP)

Este folosit pentru a trimite comenzi AV/C prin canalul L2CAP. Butoanele de control pentru muzica folosesc acest protocol pentru a controla player-ul. to control the music player.

Audio/video data transport protocol (AVDTP)

Este folosit pentru a oferi un stream musical prin canalul L2CAP catre casti.

Page 14: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

Advanced Linux Sound Architecture (ALSA) este un framework software, parte din kernelul de linux, care

ofera un API (Application programming interface) pentru driverele placilor de sunet.

Preconditii:

Pentru a realiza acest pas vom avea nevoie de urmatoarele dependinte.

sudo apt-get install pulseaudio bluez pulseaudio-module-bluetooth python-gobject python-

gobject-2

Pulseaudio – server audio specific linux ce functioneaza ca un proxy pentru aplicatiile audio;

Bluez – Bluetooth stack pentru linux ce expune interfete D-Bus pentru a fi accesat de aplicatii;

Configurari:

In fisierul /etc/bluetooth/input.conf adgaugati Enable=Source,Sink,Media,Socket – aceasta setare

permite conectarea unui device media la BT.

In fisierul /etc/pulse/daemon.conf adaugati resample-method = trivial folosim cea mai rapida

metoda de resampling pentru a evita delay-uri, daca folosim o metoda care are calitatea audio foarte

buna riscam sa avem intreruperi.

In fisierul /etc/bluetooth/main.conf adaugati Class = 0x00041C – configureaza device-ul Raspbery

PI pentru a avea tipul portable audio

Dupa finalizarea pasilor de mai sus, device-ul ar trebui sa fie complet configurat pentru a fi folosit

ca dispozitiv portable audio. Mai ramane de realizat imperecherea bluetooth intre device-ul pi si

un telefon mobil. Pentru aceasta se va deschide un terminal in cadrul Raspbian si se vor rula

urmatoarele comenzi:

sudo hciconfig hci0 piscan

sudo killall bluealsa

pulseaudio --start

bluetoothctl

power on

agent on

scan on

Explicatii:

sudo hciconfig hci0 piscan

Facem dispozitivul discoverable. Vei putea descoperi dispozitivul RPi din alte dispozitive.

sudo killall bluealsa

Pentru a putea folosi pulse audio inchidem serviciul bluealsa

Bluealsa este o integrare directa intre Bluez si ALSA. Datorita limitarilor BlueZ nu e posibil sa

folosim BlueALSA si PuluseAudio simultan.

pornim serviciul pulseaudio

Page 15: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

pulseaudio --start

PulseAudio este un proxy pentru applicatiile de sunet. Permite construirea de aplicatii complexe si

face transferal intre aplicatie si hardware. (transferal audio catre o alta masina, schimbarea

numarului de canale, sampling rate-urile, mixarea mai multor canale,etc)

bluetoothctl

Deschidem utilitarul bluetoothctl

Bluetoothctl este un client care interactioneaza cu bluetoothd din linia de comanda.

power on Trimitem comandat power on aplicatiei bluetoothctl. Se seteaza BT connectable state pe

True. Si se alimenteaza e cip-ul HCI.

agent on

Agent -ul este cel care defineste ce capabilitati are dispozitivul ("DisplayOnly", "DisplayYesNo",

"KeyboardOnly","NoInputNoOutput" and "KeyboardDisplay") si face negocierea pentru pairing.

scan on

Scan On – scaneaza lista de device-uri disponibile.

In acest moment se va afisa o lista cu dispozitivele bluetooth apropiate si adresele bluetooth

corespunzatoare. Fiecare dispozitiv bluetooth are o adresa unica reprezentata pe 48 de biti, care

este in mod frecvent abreviata ca BD_ADDR. Aceasta este reprezentata sub forma unui numar

hexazecimal cu 12 cifre de forma: XX:XX:XX:XX:XX:XX.

Mai jos se observa un exemplu de output al bluetoothctl pentru comanda scan on. Din aceasta lista

vom alege adresa corespunzatoare dispozitivului pe care vrem sa il conectam si vom da urmatoarele

comenzi in acelasi terminal:

[NEW] Device 00:1E:AE:B4:14:72 SYSTEM_NAME

[NEW] Device 48:13:7E:BC:48:A4 Galaxy S6

[NEW] Device 90:FD:61:46:7D:27 Dragos’s iPhone

[NEW] Device 76:81:9E:2B:18:70 76-81-9E-2B-18-70

[NEW] Device 5C:F3:70:8B:1A:C9 IADG540G

[NEW] Device 10:D5:42:2F:CD:66 Galaxy S4

Folosind adresa device-ului doriit, vom rula in acelasi terminal urmatoarele comenzi.

Trebuie mentionat ca dupa commanda de pair, trebuie sa se confirme passkey-ul generat atat in

terminalul bluetoothctl cat si pe telefonul mobil.

pair XX:XX:XX:XX:XX:XX

connect XX:XX:XX:XX:XX:XX

trust XX:XX:XX:XX:XX:XX

scan off exit

Pentru a verifica realizarea cu success a conexiunii A2DP se ruleaza comanda pactl list cards short.

Page 16: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

In output-ul acestei comenzi ar trebui sa se regaseasca un sound card cu denumirea

bluez_card.XX_XX_XX_XX_XX_XX.

Cursul: Sisteme Automotive – Laboratorul 1

In acest, moment daca intram in music player-ului device-ului pe care l-am conectat la pasii

anteriori, sunetul ar trebui sa fie redat prin difuzorul conectat la device-ul PI.

Tema 3: Comenzi pentru media control folosind bluetooth(AVRCP) – 1pct

In partea a doua ne propunem sa implementam o interfata grafica simpla care sa ofere controalele

necesare pentru a trimite telefonului conectat umatoarele comenzi: play, pause, next, previous,

rewind, volume up si volume down.

Principalele tehnologii pe care le vom folosi in implementarea noastra sunt:

1. GTK+ este un toolkit multi-platform ce faciliteaza dezvoltarea de interfete grafice. GTK+ ofera

un set complet de widget-uri, fiind potrivit pentru proiecte de toate dimensiunile. GTK+ este cross-

platform si ofera un API intuitiv. GTK+ este scris in limbajul de programare C, insa suporta o gama

larga de language bindings, printre care:

• C++ (gtkmm)

• Perl (Gtk2-perl)

• Ruby (ruby-gtk2)

• Python (PyGTK)

• Java (java-gnome)

• C# (Gtk#)

Pentru dezvoltarea aplicatiei noastre vom folosi binding-ul pentru Python, PyGTK.

2.D-Bus este un sistem pentru comunicare între procese (IPC). Din punct de vedere arhitectural,

acesta are mai multe straturi:

• O librărie libdbus, care face posibilă conexiunea și schimbul de mesaje între două aplicații.

• O aplicație magistrală de mesaje ( bus daemon), bazată pe libdbus, la care se pot conecta mai multe

aplicații. Această magistrală are rolul de a distribui mesajele către aplicații.

• Librării de tip “Wrapper” bazate pe anumite platforme de dezvoltare software (ex. libdbus-glib și

libdbus-qt). Există librării de legătură și către limbaje de programare precum Python. Aceste librării

de legătură oferă beneficii în sensul în care simplifică

multe detalii ce țin de implementarea folosind mecanismul D-Bus. Libdbus este menită să fie o

librărie “backend” folosibilă doar prin intermediul unor legături(bindings) de nivel mai ridicat.

Libdbus suportă doar conexiuni one-to-one, la fel precum un socket. În loc să se lucreze cu

șiruri de octeți, în cadrul mecanismului D-Bus se transmit mesaje. Mesajele au un header care conține

informația despre tipul mesajului, și un corp al mesajului ce conține mesajul util.

Bus daemon-ul reprezintă pentru acest mecanism o modalitate de a centraliza comunicarea prin

Page 17: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

D-Bus. Demon-ul este conectat la toate aplicațiile ce comunică prin D-Bus și se ocupă de repartizarea

mesajelor între aplicații. În acest sens, se poate face o analogie între funcționalitatea acestuia și

funcționalitatea unui router. Bus daemon-ul are mai multe instanțe în cadrul unui computer. Prima

instață este un singleton global la nivel de mașină. Această instanță este

protejată de restricții de securitate foarte severe în privința mesajelor pe care le acceptă și este folosită

ca mijloc de comunicare la nivel de sistem. Celelalte instanțe sunt create de fiecare dată când

utilizatorul se loghează. Aceste instanțe permit aplicațiilor din sesiunea de interacțiune cu utilizatorul

sa comunice între ele.

OBIECTE NATIVE ȘI CĂI CĂTRE OBIECTE

Framework-urile de dezvoltare software definesc conceptul de obiect, de obicei folosind o clasă

de bază. De exemplu: java.lang.Object, GObject, QObject. Aceste obiecte sunt numite obiecte

native.

Protocolul low-level D-Bus și API-ul libdbus corespunzător nu este interesat de obiectele native.

Cu toate acestea, acesta oferă un concept numit cale către obiect. Ideea unei căi către obiect este că

binding-urile de nivel ridicat pot numi instanțe de obiecte native și permit aplicațiilor de la distanță

să facă referințe la acestea.

Calea obiectului arată ca o cale de sistem de fișiere, de exemplu un obiect ar putea fi numit / org

/ kde / kspread / sheets / 3 / cells / 4/5. Căile care pot fi citite de om sunt opționale dar benefice,

însă există libertarea de a creea un obiect cu orice nume: / com / mycompany / c5yo817y0c1y1c5b,

dacă are sens pentru aplicația vizată.

METODE ȘI SEMNALE

Fiecare obiect are membri. Acești membri, în funcție de scopul lor, pot fi clasificați în metode și

semnale. Metodele sunt operațiuni care pot fi invocate în cadrul unui obiect, ce au

opțional date de intrare ( parametri) și tot opțional date de ieșire (parametri de ieșire). Semnalele

sunt tramisiunide la un obiect către observatorii obiectului. Semnalele pot sau nu conține o cantitate

informațională utilă.

INTERFEȚE

Fiecare obiect suportă una sau mai multe interfețe. O interfață poate fi privită ca un grup de

semnale și metode ce este caracterizat de o denumire. Interfețele definesc tipul unei instanțe a unui

obiect.

D-Bus identifică interfețele cu un șir de caractere precum: org.freedesktop.Introspectable.

3. BlueZ este un Bluetooth stack pentru sisteme de operare bazate pe kernelul Linux. Principalul

Page 18: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

obiectiv al BlueZ este sa implementeze specificatiile wireless standard pentru linux. Inca din anul

2006, BlueZ suporta toate protocoalele si straturile principale ale tehnologiei Bluetooth.

Printre profilurile bluetooth suportate de BlueZ se regasesc:

• HFP (Hands-Free Profile) - definește un set de funcții care facilitează utilizarea unui

telefon mobil în combinație cu un dispozitiv Hands-Free (de exemplu, instalat în mașină sau un

dispozitiv de tip cască), printr-o conexiune Bluetooth care oferă un mijloc wireless atât pentru

comanda de la distanță a telefonului mobil prin intermediul dispozitivului Hands-Free, dar și pentru

realizarea unei conexiuni audio între telefonul mobil și dispozitivul Hands-Free.

• A2DP(Advanced Audio Distribution Profile) - Profilul avansat de distribuție audio (A2DP)

definește protocoalele și proceduri care realizează distribuția conținutului audio de înaltă calitate în mono

sau stereo pe canale ACL. Un scenariu tipic de utilizare este streaming-ul de conținut muzical de la

un player muzical stereo la căști sau difuzoare. Datele audio sunt comprimate într-un format adecvat

pentru utilizarea eficientă a lățimii de bandă limitată. Distribuția sunetului surround nu este inclusă

în domeniul de aplicare al acestui profil.(Advanced Audio Distribution Profile - Bluetooth

Specification)

• AVRCP (Audio/Video Remote Control Profile) este un profil ce ofera o interfata standard pentru

a controla dispozitive TV si dispozitive Hi-Fi etc. scopul principal fiind ca utilizatorul sa dispuna

de o telecomanda universala prin care sa controleze toate echipamentele Audio/Video la care are

acces.

• MAP (Message Access Profile) - Profilul de acces la mesaje (MAP) definește caracteristicile și

procedurile care vor fi utilizate de către dispozitive care schimbă

obiecte de tip mesaj. Se bazează pe un model de interacțiune client-server unde clientul inițiază

tranzacțiile.

• PBAP (Phone Book Access Profile) - Profilul de acces în agenda telefonică (PBAP) definește

protocoalele și procedurile care trebuie să fie utilizate de dispozitive pentru

transmisia obiectelor de tip contacte telefonice. Se bazează pe un model de interacțiune client-

server în cazul în care dispozitivul client solicită obiecte din agenda telefonică din dispozitivul

server.(Phone Book Access Profile - Bluetooth Specification).

In cadrul laboratorului trecut am folosit profilul A2DP pentru a redirectiona streamingul audio

dinspre un dispozitiv catre altul. In cadrul acestui laborator, ne propunem sa folosim profilul

AVRCP. Structura unui profil bluetooth presupune o implementare low-level foarte ampla.

Aceasta este abstractizata pentru noi de BlueZ Stack, care expune interfete D-Bus pentru a accesa

direct functionalitatea relevanta pentru aplicatia noastra.

4. IDLE3 este IDE-ul ce va fi folosit pentru dezvoltare in cadrul acestui laborator. Acesta se

deschide din meniul de aplicatii, sectiunea programming.

Page 19: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

Pe desktop se gaseste un director numit lab_info. Acest director va fi locatia aplicatiei pe care o

vom dezvolta, continand resursele si dependintele externe care sunt necesare dezvoltarii aplicatiei.

Vom deschide Idle3 si vom creea un fisier nou pe desktop, in directorul lab_info.

Pentru, inceput avem nevoie de o fereastra in care sa fie continute controalele pe care le vom folosi

pentru a manipula media player-ul de pe telefon prin intermediul bluetooth.

Vom incepe prin a importa modulele necesare pentru GTK+. Vom importa gi ( Python API for

GObject Introspection). Pe langa GTK+, vom avea nevoie de GDK, o librarie ce are rolul de

wrapper in jurul functiilor low-level expuse de sistemele grafice, cum ar fi X11 si Wayland. import gi

gi.require_version('Gtk', '3.0')

from gi.repository import Gtk

gi.require_version('GdkX11', '3.0')

Page 20: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

from gi.repository import GdkX11

In continuare , vom creea o clasa ce va implementa clasa Gtk.Window. Clasa Gtk.Window ofera

caracteristicile de baza ale unui widget de tip fereastra. Aceasta clasa va contine momentan o

metoda de initializare si o metoda show. In metoda de initializare conectam semnalul “destroy” al

ferestrei la slot-ul Gtk.main_quit. Acest lucru se realizeaza pentru a intrerupe bucla de executie a

aplicatiei atunci cand utilizatorul inchide fereastra. A doua metoda are rolul de a afisa fereastra si

toate widget-urile care exista pe fereastra. class ApplicationWindow(Gtk.Window):

def __init__(self):

Gtk.Window.__init__(self, title="Media Player")

self.connect("destroy",Gtk.main_quit)

def show(self):

self.show_all()

In functia main vom instantia clasa creata mai sus, vom apela metoda show, si pornim bucla de

executiei a aplicatiei ( Gtk.main() ).

if __name__ == '__main__':

window = ApplicationWindow()

window.show()

Daca rulam acest script folosind IDLE3 ar trebui sa vedem o fereastra goala. In continuare ne dorim

sa adaugam un buton care sa gestioneze comanda de play ce ne propunem sa o trimitem catre media

player-ul telefonului. Pentru aceasta ne vom defini in clasa ApplicationWindow o metoda

setup_objects_and_events, care se va ocupa cu intitializarea si afisarea elementelor de interfata

grafica. In aceasta metoda vom defini un obiect de tip Gtk.Button(), si il vom conecta la un

slot(play_music) ce se va executa atunci cand butonul este apasat. De, asemenea , vom seta

butonului o imagine pe care o generam prin apelul Gtk.Image.new_from_icon_name. Vom adauga

acest buton intr-un grid pentru a avea un control mai bun asupra pozitionarii elementelor pe

fereastra principala pe masura ce vor aparea mai multe elemente. Elementele ce vor fi folosite din

API-ul GTK+ sunt.

Gtk.Button – un widget care emite un semnal atunci cand utilizatorul il apasa Metode folosite:

gtk_button_set_image (GtkButton *button, Gtk.Image – un widget care afiseaza o imagine.

Metode folosite:

GtkWidget *image_from_icon_name (const gchar *icon_name,

GtkIconSize size); Gtk.Grid – un widget ce aseaza alte

widget-uri pe randuri si coloane Metode folosite:

gtk_grid_attach (GtkGrid *grid, GtkWidget *child,

gint left, gint top, gint width, gint height);

Mai multe detalii despre acestea si despre modul in care pot fi folosite se gasesc la acest link

https://developer.gnome.org/gtk3/stable/.

Codul pentru a adauga un buton care afiseaza un mesaj atunci cand este apasat se gaseste mai jos: def setup_objects_and_events(self): self.playback_button = Gtk.Button()

self.play_image = Gtk.Image.new_from_icon_name( "gtk-media-play",

Page 21: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

Gtk.IconSize.DND

)

self.playback_button.set_image(self.play_image)

self.playback_button.connect("clicked", self.play_music) self.grid = Gtk.Grid()

self.add(self.grid) self.grid.attach(self.playback_button,3,0, 1, 1)

def play_music(self, widget, data=None): print("PLAY")

In functia main vom apela inainte de afisarea ferestrei metoda setup_objects and events: if name == ' main ':

window = ApplicationWindow() window.setup_objects_and_events() window.show()

Gtk.main()

TEMA 1:

Pe langa butonul play, adaugati intr-o maniera similara in fereastra butoane pentru pause, stop,

next, previous, rewind, volume_up si volume_down.

In acest scop, pentru a obtine icon-urile corespunzatoare fiecarui buton, se pot folosi:

new_from_icon_name(“ gtk-media-rewind”, Gtk.IconSize.DND)

new_from_icon_name(“ gtk-media-pause”, Gtk.IconSize.DND)

new_from_icon_name(“ gtk-media-previous”, Gtk.IconSize.DND)

new_from_icon_name(“ gtk-media-next”, Gtk.IconSize.DND)

new_from_icon_name(“ gtk-media-rewind”, Gtk.IconSize.DND)

new_from_icon_name(“ audio-volume-high”, Gtk.IconSize.DND)

new_from_icon_name(“ audio-volume-low”, Gtk.IconSize.DND)

APLICAȚII ALE D-BUS

Ne propunem sa inspectam interfetele expuse de BlueZ pe D-Bus pentru a gasi functionalitatea pe

care noi vrem sa o accesam (media control). Pentru a indeplini acest obiectiv vom folosi D- Feet.

D-Feet este un D-bus debugger usor de folosit care ofera posibilitatea de a inspecta diferitele

interefete expuse de programe pe D-Bus, dar si posibilitatea de a apela aceste metode direct din

cadrul D-Feet. In partea stanga a ferestrei vom selecta org.bluez, apoi vom cauta Object Path-ul

corespunzator device-ului la care ne-am conectat. Object path-ul are forma

/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX. In cadrul acestui object path, vom regasi diverse

interfete, printre care si org.bluez.MediaControl1. Daca inspectam, metodele expuse de aceasta

interfata vom observa ca ele ofera functionalitatea necesara pentru a controla remote media player-

ul de pe telefon. Daca deschidem aceste metode si apasam comanda Execute, ar trebui sa vedem

cum media playerul din telefon reactioneaza.

Pentru a deschide d-feet se da in terminal comanda

d-feet

Page 22: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

Ne propunem in continuare sa apelam aceste metode direct din cadrul aplicatiei dezvoltate in prima

parte a laboratorului. Pentru a realiza acest lucru mai intai este necesar sa importam modulul dbus.

import dbus

Pentru a obtine un obiect pe care sa apelam aceasta interfata in python va trebui sa parcurgem

urmatorii pasi, modificand XX_XX_XX_XX_XX_XX cu cifrele hexazecimale corespunzatoare

adresei de bluetooth a telefonului caruia ne propunem sa ii trimitem comenzile. Aceasta adresa va

fi vizibila in bluetoothctl si obiectele corespunzatoare vor apare pe d-bus numai dupa ce scanam

dispozitivele apropiate folosind bluetoothctl.

Page 23: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

bus = dbus.SystemBus()

hal_manager_object = bus.get_object('org.bluez',

'/org/bluez/hci1/dev_XX_XX_XX_XX_XX_XX') hal_manager_media_interface =

dbus.Interface(hal_manager_object, 'org.bluez.MediaControl1')

Dupa ce vom obtine obiectul ce caracterizeaza interfata pe care vrem sa o apelam pe D-bus vom

adauga in slot-urile definite anterior pentru butoane apeluri pe interfata corespunzatoare cu

functionalitatea butonului. De exemplu:

def previous_player(self, widget, data=None):

hal_manager_media_interface.Previous()

def next_player(self, widget, data=None): hal_manager_media_interface.Next()

def stop_player(self, widget, data=None): hal_manager_media_interface.Stop()

def pause_player(self, widget, data=None): hal_manager_media_interface.Pause()

def play_player(self, widget, data=None) hal_manager_media_interface.Play()

In continuare facem pair intre Raspberry Pi si dispozitivul mobil, apoi vom opri bluetoothctl:

Daca vom deschide un media player pe telefon, si vom da trimite din aplicatia noastra diferite

comenzi, vom observa ca acestea au effect in media player-ul telefonului.

Tema 4: Selectare dispozitiv folosind meniu intelligent – 1pct

sudo hciconfig hci0 piscan

pulseaudio -D

bluetoothctl

power on

agent on

scan on

pair XX:XX:XX:XX:XX:XX

connect XX:XX:XX:XX:XX:XX

trust XX:XX:XX:XX:XX:XX

scan off

exit

Page 24: Octombrie 2020 Laboratorul 1. Streaming audio folosind

ISSA – Laboratorul 1 Octombrie 2020

Solutia prezentata mai sus are dezavantajul ca trebuie sa hardcodam mereu adresa

dispozitivului la care suntem conectati pentru a avea acces la obiectul D-Bus. Ne propunem in

continuare sa selectam device-ul cu care dorim sa comunicam direct din cadrul aplicatiei

noastre. Vom realiza acest lucru prin interogarea dispozitivelor bluetooth din apropiere intr-o

metoda din clasa ApplicationWindow, si stocarea lor intr-un combo box din interfata noastra

grafica. Penturu a realiza scanarea dispozitivelor va fi necesar sa importam modulul bluetooth.

Putem folosi urmatorul icon pentru butonul bluetooth:

new_from_icon_name(“ preferences-system-bluetooth”, Gtk.IconSize.DND)

import bluetooth

Hints:

Pentru a obtine lista de dispozitive, folosim modulul bluetooth astfel: devices =

bluetooth.discover_devices(lookup_names = True) for addr, name in devices:

print (name, addr)

Pentru a oferi utilizatorului posibilitatea de a selecta device-ul a carui interfata AVRCP vrea sa o

acceseze, se poate folosi un widget de tip ComboBox in combinatie cu un obiect de tip ListStore.

self.resultModel = Gtk.ListStore(str,str) self.resultCombo = Gtk.ComboBox.new()

Spre deosebire de buton, pentru care inputul utilizatorului era primit prin semnalul “clicked”, in

cazul pentru un obiect de tip combo box se emite semnalul “changed” de fiecare data cand este

selectat un item. De exemplu putem determina o schimbare in combo box sa declanseze un slot din

aplicatia noastra astfel:

self.resultCombo.connect("changed", self.on_combo_changed)

Exemplu de layout pentru aplicatie: