একটি অ্যাপ্লিকেশন নিঃশব্দ করার স্ক্রিপ্ট


14

আমার লক্ষ্য হ'ল স্পোটাইফাই অ্যাপ্লিকেশনটি নিঃশব্দ করতে সক্ষম হবে, পুরো সিস্টেমটি নয়। কমান্ডটি ব্যবহার করে: ps -C spotify -o pid=আমি স্পটিফাইয়ের প্রসেস আইডিটি সন্ধান করতে সক্ষম, এই ক্ষেত্রে আইডিটি "22981"। যে প্রক্রিয়ার সঙ্গে আইডি আমি এই তালিকা থেকে অনুসন্ধান করতে চায়: pacmd list-sink-inputs। কমান্ডটি এই জাতীয় একটি তালিকা ফিরিয়ে দেয়:

eric@eric-desktop:~$ pacmd list-sink-inputs
Welcome to PulseAudio! Use "help" for usage information.
>>> 1 sink input(s) available.
    index: 0
    driver: <protocol-native.c>
    flags: START_CORKED 
    state: RUNNING
    sink: 1 <alsa_output.pci-0000_00_1b.0.analog-stereo>
    volume: 0: 100% 1: 100%
            0: -0.00 dB 1: -0.00 dB
            balance 0.00
    muted: no
    current latency: 1019.80 ms
    requested latency: 371.52 ms
    sample spec: s16le 2ch 44100Hz
    channel map: front-left,front-right
                 Stereo
    resample method: (null)
    module: 8
    client: 10 <Spotify>
    properties:
        media.role = "music"
        media.name = "Spotify"
        application.name = "Spotify"
        native-protocol.peer = "UNIX socket client"
        native-protocol.version = "26"
        application.process.id = "22981"
        application.process.user = "eric"
        application.process.host = "eric-desktop"
        application.process.binary = "spotify"
        window.x11.display = ":0"
        application.language = "en_US.UTF-8"
        application.process.machine_id = "058c89ad77c15e1ce0dd5a7800000012"
        application.process.session_id = "058c89ad77c15e1ce0dd5a7800000012-1345692739.486413-85297109"
        application.icon_name = "spotify-linux-512x512"
        module-stream-restore.id = "sink-input-by-media-role:music"

এখন আমি application.process.id = "22981"সিঙ্ক ইনপুট সূচীর সাথে সম্পর্কিত করতে চাই যা এই ক্ষেত্রে index: 0। এখন সেই সূচী নম্বরটি নিয়ে আমার তখন এই কমান্ডটি চালানো দরকার: pacmd set-sink-input-mute 0 1স্পটিফাইটি নিঃশব্দ করা এবং pacmd set-sink-input-mute 0 0স্পটিফাইটি সশব্দ করা। এই কমান্ডগুলির জন্য, প্রথম নম্বরটি আগে পাওয়া সূচক সংখ্যাটির সাথে প্রতিস্থাপন করা প্রয়োজন এবং পরবর্তী নম্বরটি নিঃশব্দ চালু বা বন্ধ করার জন্য বুলিয়ান। আমি কীভাবে এটি পুরোপুরি স্ক্রিপ্টে রাখতে পারি, যাতে আমি স্পটিফাই অ্যাপ্লিকেশনটি নিঃশব্দ / নিঃশব্দ করার জন্য একটি আদেশ পেতে পারি?

সম্পাদনা করুন: কাজ আশানুরূপ নিচে স্ক্রিপ্ট দুজনেই পারেন কারো একটি টগল যা পরীক্ষা হবে যোগ muted: yesবা muted: noএবং তারপর নিঃশব্দ অথবা সশব্দ তদনুসারে?

সম্পাদনা: টগল যোগ করতে আমি গ্লেন জ্যাকম্যানের স্ক্রিপ্টটি সংশোধন করতে সক্ষম হয়েছি:

#!/bin/bash

main() {
    local action=toggle
    while getopts :mu option; do 
        case "$option" in 
            m) action=mute ;;
            u) action=unmute ;;
            ?) usage 1 "invalid option: -$OPTARG" ;;
        esac
    done
    shift $((OPTIND - 1))
    local pid=$(pidof "$1")
    if [[ -z "$pid" ]]; then
        echo "error: no running processes for: $1" >&2
    elif [[ "$1" ]]; then
        $action "$1"
    else
        usage 1 "specify an application name" 
    fi
}

usage() {
    [[ "$2" ]] && echo "error: $2"
    echo "Usage: $0 [-m | -u] appname"
    echo "Default: toggle mute"
    echo "Arguments:"
    echo "-m = mute application"
    echo "-u = unmute application"
    exit $1
}

toggle() {
    local status=$(get_status "$1")
    if [[ "$status" == "yes" ]]; then
      unmute "$1"
    elif [[ "$status" == "no" ]]; then
      mute "$1"
    fi
}

mute()   { adjust_muteness "$1" 1; }
unmute() { adjust_muteness "$1" 0; }

adjust_muteness() { 
    local index=$(get_index "$1")
    local status=$(get_status "$1")
    [[ "$index" ]] && pacmd set-sink-input-mute "$index" $2 >/dev/null 
}

get_index() {
    local pid=$(pidof "$1")
    pacmd list-sink-inputs | 
    awk -v pid=$pid '
    $1 == "index:" {idx = $2} 
    $1 == "application.process.id" && $3 == "\"" pid "\"" {print idx; exit}
    '
}

get_status() {
   local pid=$(pidof "$1")
   pacmd list-sink-inputs | 
   awk -v pid=$pid '
   $1 == "muted:" {idx = $2} 
   $1 == "application.process.id" && $3 == "\"" pid "\"" {print idx; exit}
   '
}

main "$@"

কেন ব্যবহার pactl list sink-inputsকরবেন না ? তারপরে এটি নেটওয়ার্কে কাজ করবে।
জানুস ট্রয়েলসন

উত্তর:


13

আপনার আকর্ষণীয় চ্যালেঞ্জটি গ্রহণ করার জন্য এটি এখানে:

#!/bin/bash

main() {
    local action=mute
    while getopts :hu option; do 
        case "$option" in 
            h) usage 0 ;;
            u) action=unmute ;;
            ?) usage 1 "invalid option: -$OPTARG" ;;
        esac
    done
    shift $((OPTIND - 1))

    if [[ "$1" ]]; then
        $action "$1"
    else
        usage 1 "specify an application name" 
    fi
}

usage() {
    [[ "$2" ]] && echo "error: $2"
    echo "usage: $0 [-h] [-u] appname"
    echo "where: -u = ummute application (default action is to mute)"
    exit $1
}

mute()   { adjust_muteness "$1" 1; }
unmute() { adjust_muteness "$1" 0; }

adjust_muteness() { 
    local index=$(get_index "$1")
    [[ "$index" ]] && pacmd set-sink-input-mute "$index" $2 >/dev/null 
}

get_index() {
    local pid=$(pidof "$1")
    if [[ -z "$pid" ]]; then
        echo "error: no running processes for: $1" >&2
    else
        pacmd list-sink-inputs | 
        awk -v pid=$pid '
            $1 == "index:" {idx = $2} 
            $1 == "application.process.id" && $3 == "\"" pid "\"" {print idx; exit}
        '
    fi
}

main "$@"

এটি পুরোপুরি পাশাপাশি কাজ করে
যুগ 878

@ যুগ 878, আমি ডিফল্ট ক্রিয়া হিসাবে টগল করার ধারণাটি পছন্দ করি। তবে আপনার get_statusফাংশনটি "নিঃশব্দ" রেখাগুলি ক্রস-চেক না করেই খুঁজে পাবে যে স্থিতিটি উপযুক্ত অ্যাপ্লিকেশনের অন্তর্ভুক্ত। get_indexবিশদ জন্য আমার ফাংশন পুনরায় পড়ুন ।
গ্লেন জ্যাকম্যান

3
চমৎকার
অ্যাডক

@glennjackman, হ্যাঁ, আমি কিছুক্ষণ পরে এটি বুঝতে পেরেছি। আমি বিশ্বাস করি যে আমি যে স্ক্রিপ্টটি পোস্ট করেছি তা এখন সঠিকভাবে কাজ করে।
যুগ 878

1
বিবরণ: awk -v var=val। আওক লাইনগুলিতে লুপ করে, 1 বাই 1 করে, যে কোনও $1 == ...বিবৃতিটি মেলানোর চেষ্টা করে, ম্যাচে ব্র্যাকেটে কোড কার্যকর করে, এবং অবিরত থাকে। যার প্রথম শব্দটি সেই লাইনে প্রথম বিবৃতি মেলে index:এবং দ্বিতীয় শব্দের (SINK INDEX) idxপরিবর্তনশীলতে সঞ্চয় করে। সুতরাং idxপরবর্তী দ্বারা ওভাররাইট পায় index: <SINK INDEX>লাইন পর্যন্ত awk দ্বিতীয় বিবৃতি সাথে মিলে যায় ( $1= application.process.id, $2= =, $3= <expected pid val>)। যখন এই ২ য় বিবৃতিটি মেলে, তখন অদ্বিতীয় প্রিন্টগুলি idx(এটি সর্বশেষ লাইন যা প্রথম বিবৃতিটির সাথে মেলে index:) এবং প্রস্থান করে।
ক্রিসওয়েডদেভ

7

সমাধানের জন্য ধন্যবাদ! আমি আমার সমস্যা সমাধানের জন্য এখানে প্রদত্ত স্ক্রিপ্টগুলি ব্যবহার করতে সক্ষম হয়েছি। যেহেতু আমাকে তাদের কিছুটা সংশোধন করতে হয়েছিল, তাই আমি এখানে উন্নত সংস্করণে যোগদান করি।

মূল স্ক্রিপ্টগুলি আমার পক্ষে কাজ না করার কারণটি হ'ল কিছু অ্যাপ্লিকেশনগুলিতে বেশ কয়েকটি উদাহরণ থাকতে পারে, অর্থাত্ বেশ কয়েকটি পিআইডি, তবে সম্ভবত তাদের মধ্যে একটিরই শব্দ উত্পন্ন করছে, এবং এটি আসলে পালসৌডিওর সাথে সংযুক্ত। যেহেতু স্ক্রিপ্টটি কেবল পাওয়া প্রথম পিআইডি ব্যবহার করেছে, এটি সাধারণত / পছন্দ করে না / পছন্দসই অ্যাপ্লিকেশনটি নিঃশব্দ করে।

সুতরাং এখানে এমন একটি সংস্করণ রয়েছে যেখানে যুক্তিটি হ'ল পালস অডিওতে নিবন্ধভুক্ত অ্যাপ্লিকেশন নাম। আপনি pacmd list-sink-inputsকমান্ডটি চালিয়ে এই নামটি খুঁজে পেতে পারেন এবং application.nameক্ষেত্রের সন্ধান করতে পারেন ।

বিকল্প সমাধান হ'ল সমস্ত পিআইডিগুলিকে নিঃশব্দ / নিঃশব্দ করা যাতে একই অ্যাপ্লিকেশন নাম রয়েছে।

#!/bin/bash

# Adapter from glenn jackman on http://askubuntu.com/questions/180612/script-to-mute-an-application
# to depend directly on the name of the PulseAudio client
# rather than the application name (several instances of one application could
# run while only one is connected to PulseAudio)

# Possible further improvement: it could be useful to also mute all clients having
# the specified name. Here, only the first one is muted.

#!/bin/bash

main() {
    local action=mute
    while getopts :hu option; do
        case "$option" in
            h) usage 0 ;;
            u) action=unmute ;;
            ?) usage 1 "invalid option: -$OPTARG" ;;
        esac
    done
    shift $((OPTIND - 1))

    if [[ "$1" ]]; then
        $action "$1"
    else
        usage 1 "specify the name of a PulseAudio client"
    fi
}

usage() {
    [[ "$2" ]] && echo "error: $2"
    echo "usage: $0 [-h] [-u] appname"
    echo "where: -u = ummute application (default action is to mute)"
    exit $1
}

mute()   { adjust_muteness "$1" 1; }
unmute() { adjust_muteness "$1" 0; }

adjust_muteness() {
    local index=$(get_index "$1")
    if [[ -z "$index" ]]; then
        echo "error: no PulseAudio sink named $1 was found" >&2
    else
        [[ "$index" ]] && pacmd set-sink-input-mute "$index" $2 >/dev/null
    fi
}

get_index() {
#    local pid=$(pidof "$1")
#    if [[ -z "$pid" ]]; then
#        echo "error: no running processes for: $1" >&2
#    else
        pacmd list-sink-inputs |
        awk -v name=$1 '
            $1 == "index:" {idx = $2}
            $1 == "application.name" && $3 == "\"" name "\"" {print idx; exit}
        '
#    fi
}

main "$@"

6

যদিও প্রশ্নটি কোনও স্ক্রিপ্টের জন্য জিজ্ঞাসা করছে, আমি এটি এখানে রেখে যেতে চেয়েছিলাম।

আমি একটি সি অ্যাপ্লিকেশন লিখেছি যা উবুন্টুতে এটি করে। আরও ভাল, এটি সূচক ট্রেতে (ব্যবহার করে libappindicator) বসে এবং স্পোটাইফাই কী খেলছে তা যাচাই করে, সংক্ষিপ্ত বিরতিতে। যদি এটি কোনও বিজ্ঞাপন খেলছে (কোনও কালো তালিকাভুক্তের বিরুদ্ধে পরীক্ষা করে) এটি স্পটিফাইটি নিঃশব্দ করে। যদি কোনও নতুন বিজ্ঞাপন প্লে হচ্ছে তবে আপনি সূচক মেনুতে কেবল নিঃশব্দে ক্লিক করুন এবং এটি কালো তালিকাতে যুক্ত করুন।

এটি যা করে তা হ'ল এক্স উইন্ডো সন্ধান করা হয়, যার জন্য XFetchNameফিরে আসে Spotify - Linux Preview। তারপরে এটি সেই উইন্ডোটির সম্পত্তিটি XGetWindowPropertyজিজ্ঞাসা করার জন্য কল করে _NET_WM_ICON_NAME, যা "Spotify – <Artist> – <Song>"ফর্ম্যাটে একটি স্ট্রিং দেয় । বিজ্ঞাপনগুলি খেললে, এটি এমন কিছু ফেরত দেয়:

"Spotify – Spotify – Premium Free Trial Cancel Any Time"

এটি বর্তমান তালিকার তালিকায় রয়েছে কিনা তা দক্ষতার সাথে পরীক্ষা করার জন্য বিজ্ঞাপনগুলির তালিকার একটি টের্নারি অনুসন্ধান বৃক্ষ বজায় রাখে ।

এটি জিজ্ঞাসা করতে এবং এর জন্য পালস অডিও অ্যাসিনক্রোনাস এপিআইও ব্যবহার করে :sink-inputsset-mute

pa_context_get_sink_input_info_list()
pa_context_set_sink_input_mute()

যেহেতু এটি কেবল সাধারণ সি কোড, এটি হালকা ওজন। উত্স কোড এবং উবুন্টু .debপ্যাকেজটি এখানে দেখুন: সূচক-মুটিড । এটি সম্ভবত শেল স্ক্রিপ্টটি 2-3 মাপের অর্ডার দ্বারা পরাজিত করবে।


1.0.11 সংস্করণটির সাথে কাজ করে না
জানুস

4

প্রথমত, স্পটফাইফের মতো একটি অ্যাপ্লিকেশনটির পিআইডি সন্ধানের "আরও সঠিক" উপায়টি হ'ল:

pidof spotify

আমি একটি স্ক্রিপ্ট তৈরি করেছি যা কাজটি করে, আমি জানি না এটি করার সর্বোত্তম উপায় কিনা তবে এটি পুরোপুরি কার্যকর হয়:

#!/bin/bash
# Script to mute an application using PulseAudio, depending solely on
# process name, constructed as answer on askubuntu.com: 
# http://askubuntu.com/questions/180612/script-to-mute-an-application

#It works as: mute_application.sh vlc mute OR mute_application.sh vlc unmute

if [ -z "$1" ]; then
   echo "Please provide me with an application name"
   exit 1
fi

if [ -z "$2" ]; then
   echo "Please provide me with an action mute/unmute after the application name"
   exit 1
fi

if ! [[ "$2" == "mute" || "$2" == "unmute" ]]; then
   echo "The 2nd argument must be mute/unmute"
   exit 1
fi

process_id=$(pidof "$1")

if [ $? -ne 0 ]; then
   echo "There is no such process as "$1""
   exit 1
fi

temp=$(mktemp)

pacmd list-sink-inputs > $temp

inputs_found=0;
current_index=-1;

while read line; do
   if [ $inputs_found -eq 0 ]; then
      inputs=$(echo -ne "$line" | awk '{print $2}')
      if [[ "$inputs" == "to" ]]; then
         continue
      fi
      inputs_found=1
   else
      if [[ "${line:0:6}" == "index:" ]]; then
         current_index="${line:7}"
      elif [[ "${line:0:25}" == "application.process.id = " ]]; then
         if [[ "${line:25}" == "\"$process_id\"" ]]; then
            #index found...
            break;
         fi
      fi
   fi
done < $temp

rm -f $temp

if [ $current_index -eq -1 ]; then
   echo "Could not find "$1" in the processes that output sound."
   exit 1
fi

#muting...
if [[ "$2" == "mute" ]]; then
   pacmd set-sink-input-mute "$current_index" 1 > /dev/null 2>&1
else
   pacmd set-sink-input-mute "$current_index" 0 > /dev/null 2>&1
fi

exit 0

আপনি এইভাবে কাজ করতে পারেন:

./mute_application.sh spotify mute

অথবা

./mute_application.sh spotify unmute

দু: সাহসিক এবং ভিএলসি উভয়ই চালিত এবং নিঃশব্দ / নিঃশব্দ করা তাদের উভয়ের সাথেই পরীক্ষিত।


নিখুঁত স্ক্রিপ্ট, প্রত্যাশিত হিসাবে কাজ করে
বয়স 878

1

আমি সত্যিই স্ক্রিপ্ট করতে পারছি না, তবে আমি অন্যটি তৈরি করতে হ্যাকারমানিয়ার স্ক্রিপ্ট পরিবর্তন করেছি।

এইটি 5% বর্ধিত সময়ে নির্দিষ্ট অ্যাপ্লিকেশনটির পরিমাণ বৃদ্ধি বা হ্রাস করবে:

সম্পাদনা: প্রকৃতপক্ষে, এটি সর্বদা সর্বশেষ খোলার অ্যাপ্লিকেশন পরিবর্তনে কাজ করে। ধারনা?

#!/bin/bash
# Script to increase or decrease an individual application's volume using PulseAudio, depending solely on
# process name, based on another script by hakermania, constructed as answer on askubuntu.com: 
# http://askubuntu.com/questions/180612/script-to-mute-an-application

# It works as: change_app_volume.sh vlc increase OR change_app_volume.sh vlc decrease
# Set desired increments in lines #66 and #68

if [ -z "$1" ]; then
   echo "Please provide me with an application name"
   exit 1
fi

if [ -z "$2" ]; then
   echo "Please provide me with an action increase/decrease after the application name"
   exit 1
fi

if ! [[ "$2" == "increase" || "$2" == "decrease" ]]; then
   echo "The 2nd argument must be increase/decrease"
   exit 1
fi

process_id=$(pidof "$1")

if [ $? -ne 0 ]; then
   echo "There is no such process as "$1""
   exit 1
fi

temp=$(mktemp)

pacmd list-sink-inputs > $temp

inputs_found=0;
current_index=-1;

while read line; do
   if [ $inputs_found -eq 0 ]; then
      inputs=$(echo -ne "$line" | awk '{print $2}')
      if [[ "$inputs" == "to" ]]; then
         continue
      fi
      inputs_found=1
   else
      if [[ "${line:0:6}" == "index:" ]]; then
         current_index="${line:7}"
      elif [[ "${line:0:25}" == "application.process.id = " ]]; then
         if [[ "${line:25}" == "\"$process_id\"" ]]; then
            #index found...
            break;
         fi
      fi
   fi
done < $temp

rm -f $temp

if [ $current_index -eq -1 ]; then
   echo "Could not find "$1" in the processes that output sound."
   exit 1
fi

#increase/decrease...
if [[ "$2" == "increase" ]]; then
   pactl set-sink-input-volume "$current_index" +5% > /dev/null 2>&1
else
   pactl set-sink-input-volume "$current_index" -5% > /dev/null 2>&1
fi

exit 0

0

কোনও অ্যাপ্লিকেশন (একাধিক প্রক্রিয়া) এর সমস্ত ইনপুট নিঃশব্দ করতে স্ক্রিপ্ট সম্পাদনা করা হয়েছে এবং টগল করতে ডিফল্ট:

#!/bin/bash

main() {
    local action=toggle
    while getopts :hu option; do
        case "$option" in
            h) usage 0 ;;
            m) action=mute ;;
            u) action=unmute ;;
            ?) usage 1 "invalid option: -$OPTARG" ;;
        esac
    done
    shift $((OPTIND - 1))

    if [[ "$1" ]]; then
        $action "$1"
    else
        usage 1 "specify an application name"
    fi
}

usage() {
    [[ "$2" ]] && echo "error: $2"
    echo "usage: $0 [-h] [-u] appname"
    echo "where: -u = ummute , -m = mute (default action is to toggle)"
    exit $1
}

mute()   { adjust_muteness "$1" 1; }
unmute() { adjust_muteness "$1" 0; }
toggle() { adjust_muteness "$1" toggle; }

adjust_muteness() {
    clients=$(pactl list clients short | awk '/[0-9]+.*'$1'.*/{print $1}')
    inputs=$(pactl list sink-inputs short)
    for c in $clients; do
        for i in $(printf '%s' "$inputs" | awk '/[0-9]+\s[0-9]+\s'$c'/{print $1}'); do
            pactl set-sink-input-mute $i $2 &
        done
    done
}

main "$@"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.