FFMPEG: Cut out last 10 seconds of wave/mp3 - ffmpeg

I'm using ffmpeg to convert my files from wave to mp3. But for a new service I need to cut out the last 10 seconds of some of the songs (for piracy issues), no matter how long they are. I've only found information about doing this when the length of the track has been known, but for this I need to do it automatically.
Does anyone know which command to use? If I can fade-out 5 seconds before that would be optimal!

python is a powerfull tool for almost everything (tested in linux)
#!/bin/python
from sys import argv
from os import system
from subprocess import Popen, PIPE
ffm = 'ffmpeg -i' # input file
aud = ' -acodec mp3' #add your quality preferences
dur = ' 2>&1 | grep "Duration" | cut -d " " -f 4'
def cutter(inp,t=0):
out = inp[:-5] + '_cut' + inp[-5:]
cut = ' -t %s' % ( duration(inp)-t )
cmd = ffm + inp + aud + cut + out
print cmd; system(cmd)
def fader(inp,t=0):
out = inp[:-5] + '_fade' + inp[-5:]
fad = ' -af "afade=t=out:st=%s:d=%s"' % ( duration(inp)-t, t )
cmd = ffm + inp + fad + out
print cmd; system(cmd)
def duration(inp):
proc = Popen(ffm + inp + dur, shell=True, stdout=PIPE, stderr=PIPE)
out,err = proc.communicate()
h,m,s = [float(x) for x in out[:-2].split(':')]
return (h*60 + m)*60 + s
if __name__ == '__main__':
fname=' "'+argv[1]+'"'
cutter(fname,10)
fader (fname, 5)
# $ python cut_end.py "audio.mp3"
To fade-out the command is
ffmpeg -i audio.mp3 -af "afade=t=out:st=65:d=5" test.mp3
t: type (in|out)
st: start time
d: duration
To automate
for i in *wav;do python cut_end.py "$i";done
You can concatenate (cutter->fader) to do what you want.
Regards.

Related

sed: no input files

I have a script where I read in columns of data from an "input file", then use those to change some variables in another file.
Here is my script, titled FA_grid_changer.sh
#!/bin/bash
# before runnning, please ensure your inlist has the following parameters: RSP_mass, RSP_Teff, RSP_L, RSP_X, RSP_Z,
# log_directory, photo_directory, RSP_alfa, photo_interval, profile_interval, history_interval, terminal_interval,
# max_num_profile_models, RSP_max_num_periods
export OMP_NUM_THREADS=8
# get current directory
dir=$PWD
data_file="$dir"/input.dat
mesa_inlist="$dir"/inlist_rsp_RR_Lyrae
# set STR to 1 for saving history and profile files BEFORE the model has reached full-amplitude pulsations
# set STR to 2 for saving history and profile files AFTER the model has reached full-amplitude pulsations
STR=1
max_num_periods=4000
max_num_periods_2=$(($max_num_periods + 4))
if [[ "$STR" = 1 ]]
then
echo Configuring inlist to save settings before full-amplitude pulsations...
sed -i \
-e "s/^\([[:blank:]]*photo_interval\).*/\1 = 1000/i" \
-e "s/^\([[:blank:]]*profile_interval\).*/\1 = 1000/i" \
-e "s/^\([[:blank:]]*history_interval\).*/\1 = 1000/i" \
-e "s/^\([[:blank:]]*terminal_interval\).*/\1 = 4000/i" \
-e "s/^\([[:blank:]]*max_num_profile_models\).*/\1 = 100/i" \
-e "s/^\([[:blank:]]*RSP_max_num_periods\).*/\1 = $max_num_periods/i" \
"$mesa_inlist"
sleep 1.5
while read -ra fields; do
echo Changing model parameters...
sleep 0.5
sed -i \
-e "s/^\([[:blank:]]*RSP_mass\).*/\1 = ${fields[3]}/i" \
-e "s/^\([[:blank:]]*RSP_Teff\).*/\1 = ${fields[5]}/i" \
-e "s/^\([[:blank:]]*RSP_L\).*/\1 = ${fields[4]}/i" \
-e "s/^\([[:blank:]]*RSP_X\).*/\1 = ${fields[2]}/i" \
-e "s/^\([[:blank:]]*RSP_Z\).*/\1 = ${fields[1]}/i" \
-e "s/^\([[:blank:]]*log_directory\).*/\1 = 'LOGS\/LOGS_${fields[0]}'/i" \
-e "s/^\([[:blank:]]*photo_directory\).*/\1 = 'photos\/photos_${fields[0]}'/i" \
#-e "s/^\([[:blank:]]*RSP_alfa\).*/\1 = ${fields[6]}/i" \
"$mesa_inlist"
echo Compiling MESA...
sleep 0.5
./mk
echo Running MESA...
sleep 0.5
./rn
done < "$data_file"
elif [[ "$STR" = 2 ]]
then
echo Configuring inlist to save settings after full-amplitude pulsations...
sed -i \
-e "s/^\([[:blank:]]*photo_interval\).*/\1 = 1000/i" \
-e "s/^\([[:blank:]]*profile_interval\).*/\1 = 1/i" \
-e "s/^\([[:blank:]]*history_interval\).*/\1 = 1/i" \
-e "s/^\([[:blank:]]*terminal_interval\).*/\1 = 4000/i" \
-e "s/^\([[:blank:]]*max_num_profile_models\).*/\1 = -1/i" \
-e "s/^\([[:blank:]]*RSP_max_num_periods\).*/\1 = $max_num_periods_2/i" \
"$mesa_inlist"
sleep 1.5
else
echo STR\: Not an acceptable option. Please \set STR to 1 or 2.
fi
Here is my input file input.dat, which I am keeping in the same directory.
RRL1 0.001 0.749 0.61036165206037 48.3930329458203 6795.10018238295
RRL2 0.001 0.749 0.60627327846453 59.8125833648911 6793.11236483182
RRL3 0.001 0.749 0.606272337551755 56.5141274900899 7059.10474568471
And here is the file I am trying to change inlist_rsp_RR_Lyrae
! long-period RR Lyrae star: M=0.65Ms, L=60Ls, Teff=6500K, X=0.75, Z=0.0004
! original test case contributed by Radek Smolec.
&star_job
!pgstar_flag = .true.
/ ! end of star_job namelist
&controls
! check for retries and backups as part of test_suite
!max_number_retries = -1
!max_number_backups = 0
!max_model_number = 15000
! RSP controls
! x_integer_ctrl(1) = 10 ! which period to check
x_ctrl(1) = 0.71262d0 ! expected period (in days)
RSP_mass = 0.606272337551755
RSP_Teff = 7059.10474568471
!RSP_L = 59.3141274900899
RSP_L = 56.5141274900899
RSP_X = 0.749
RSP_Z = 0.001
RSP_max_num_periods = 4000
RSP_nmodes = 10 ! number of modes LINA will calculate for initial model
RSP_nz = 150 ! number of zones of model
log_directory = 'LOGS/LOGS_M081_second'
photo_directory = 'photos/photos_M081_second'
! output controls
!num_trace_history_values = 2
trace_history_value_name(1) = 'rel_E_err'
trace_history_value_name(2) = 'log_rel_run_E_err'
! for cases in which you have a run that has reached steady pulses
! and you want to look at plots of just a few periods to see the details,
! i suggest the following method. interrupt the run soon after
! it makes a photo. remove or delete LOGS/history.data to force
! creation of a new one when restart. edit the inlist to set
! history_interval to 1 to get maximum time resolution.
! restart the run and let it go for as many periods as desired.
do_history_file = .true.
photo_interval = 1000
profile_interval = 1000
history_interval = 1000
terminal_interval = 4000
max_num_profile_models = 100
!photo_interval = 1
!profile_interval = 1
!history_interval = 1
!terminal_interval = 1
! FOR DEBUGGING
!RSP_report_undercorrections = .true.
!report_hydro_solver_progress = .true. ! set true to see info about newton iterations
!report_ierr = .true. ! if true, produce terminal output when have some internal error
!stop_for_bad_nums = .true.
!trace_evolve = .true.
! hydro debugging
!hydro_check_everything = .true.
!hydro_inspectB_flag = .true.
!hydro_sizequ_flag = .true.
! for making logs, uncomment hydro_dump_call_number plus the following
! to make residual logs, uncomment hydro_sizequ_flag
! to make correction logs, uncomment hydro_inspectB_flag
! to make jacobian logs, uncomment hydro_numerical_jacobian, hydro_save_numjac_plot_data
! to do dfridr test, uncomment hydro_get_a_numerical_partial, hydro_test_partials_k,
! hydro_numerical_jacobian, hydro_save_numjac_plot_data, hydro_dump_iter_number
!hydro_get_a_numerical_partial = 1d-7
!hydro_test_partials_k = 190
!hydro_numerical_jacobian = .true.
!hydro_save_numjac_plot_data = .true.
!hydro_dump_call_number = 1
!hydro_dump_iter_number = 6
!hydro_epsder_struct = 1d-6
!hydro_epsder_chem = 1d-6
!hydro_save_photo = .true. ! Saves a photo when hydro_call_number = hydro_dump_call_number -1
!fill_arrays_with_NaNs = .true.
!report_why_dt_limits = .true.
!report_all_dt_limits = .true.
!report_hydro_dt_info = .true.
!report_dX_nuc_drop_dt_limits = .true.
!report_bad_negative_xa = .true.
!show_mesh_changes = .true.
!mesh_dump_call_number = 95
!trace_newton_bcyclic_solve_input = .true. ! input is "B" j k iter B(j,k)
!trace_newton_bcyclic_solve_output = .true. ! output is "X" j k iter X(j,k)
!trace_newton_bcyclic_matrix_input = .true.
!trace_newton_bcyclic_matrix_output = .true.
!trace_newton_bcyclic_steplo = 1 ! 1st model number to trace
!trace_newton_bcyclic_stephi = 1 ! last model number to trace
!trace_newton_bcyclic_iterlo = 2 ! 1st newton iter to trace
!trace_newton_bcyclic_iterhi = 2 ! last newton iter to trace
!trace_newton_bcyclic_nzlo = 1 ! 1st cell to trace
!trace_newton_bcyclic_nzhi = 10000 ! last cell to trace; if < 0, then use nz as nzhi
!trace_newton_bcyclic_jlo = 1 ! 1st var to trace
!trace_newton_bcyclic_jhi = 100 ! last var to trace; if < 0, then use nvar as jhi
!trace_k = 0
/ ! end of controls namelist
&pgstar
!pause = .true.
pgstar_interval = 6
Grid2_win_flag = .true.
Grid2_title = '4.165 M\d\(2281)\u Z=0.007 Classical Cepheid'
History_Panels1_xaxis_name='star_age_day'
History_Panels1_max_width = 365 ! only used if > 0. causes xmin to move with xmax.
! Grid2_file_flag = .true.
file_digits = 7
Grid2_file_dir = 'png'
Grid2_file_prefix = 'grid'
Grid2_file_interval = 5 ! output when mod(model_number,Grid2_file_interval)==0
!Profile_Panels1_show_grid = .true.
Profile_Panels1_xaxis_name = 'logtau'
Profile_Panels1_xaxis_reversed = .true.
Profile_Panels1_xmin = -101D0
Profile_Panels1_xmax = -101D0
Profile_Panels1_dymin(4) = 0.02
Profile_Panels1_yaxis_name(2) = 'avg_charge_He'
/ ! end of pgstar namelist
Yet, when I try to run the shell script in bash, inlist_rsp_RR_Lyrae remains unchanged. Instead, this occurs:
Configuring inlist to save settings before full-amplitude pulsations...
Changing model parameters...
sed: no input files
/home/nick/mesa-r11701/star/test_suite/rsp_RR_Lyrae_grid/inlist_rsp_RR_Lyrae: line 1: long-period: command not found
/home/nick/mesa-r11701/star/test_suite/rsp_RR_Lyrae_grid/inlist_rsp_RR_Lyrae: line 3: original: command not found
/home/nick/mesa-r11701/star/test_suite/rsp_RR_Lyrae_grid/inlist_rsp_RR_Lyrae: line 5: syntax error near unexpected token `&'
/home/nick/mesa-r11701/star/test_suite/rsp_RR_Lyrae_grid/inlist_rsp_RR_Lyrae: line 5: `&star_job'
Compiling MESA...
As you can see, it is mistaking the first few lines of comments in inlist_rsp_RR_Lyrae as commands. Is there something I am missing here?
The problem is
sed -i \
...
-e "s/^\([[:blank:]]*photo_directory\).*/\1 = 'photos\/photos_${fields[0]}'/i" \
#-e "s/^\([[:blank:]]*RSP_alfa\).*/\1 = ${fields[6]}/i" \
"$mesa_inlist"
Here the comment before $mesa_inlist also comments out the \ at the end of the line. Therefore the command ends at that comment and sed -i complains that there is no file given. Afterwards bash tries to execute "$mesa_inlist" (that is inlist_rsp_RR_Lyrae) as a command, which fails.
To fix the problem, simply remove the comment line.
Bye the way: With this function you can drastically improve the readability of your script.
sedi() {
mapfile -t args < <(printf -- '-e\ns/^\([[:blank:]]*%s\).*/\\1 = %s/i\n' "$#")
sed -i "${args[#]}" "$mesa_inlist"
}
Now you can replace ...
sed -i \
-e "s/^\([[:blank:]]*photo_interval\).*/\1 = 1000/i" \
-e "s/^\([[:blank:]]*profile_interval\).*/\1 = 1/i" \
-e "s/^\([[:blank:]]*history_interval\).*/\1 = 1/i" \
-e "s/^\([[:blank:]]*terminal_interval\).*/\1 = 4000/i" \
-e "s/^\([[:blank:]]*max_num_profile_models\).*/\1 = -1/i" \
-e "s/^\([[:blank:]]*RSP_max_num_periods\).*/\1 = $max_num_periods_2/i" \
"$mesa_inlist"
... by ...
sedi \
photo_interval 1000 \
profile_interval 1 \
history_interval 1 \
terminal_interval 4000 \
max_num_profile_models -1 \
RSP_max_num_periods "$max_num_periods_2"
... and so on for the other sed commands.

Change back DPI settings in a bash script

I would like to run a program that does not properly support my desired resolution+DPI settings.
Also I want to change my default GTK theme to a lighter one.
What I currently have:
#!/bin/bash
xfconf-query -c xsettings -p /Xft/DPI -s 0
GTK_THEME=/usr/share/themes/Adwaita/gtk-2.0/gtkrc /home/unknown/scripts/ch_resolution.py --output DP-0 --resolution 2560x1440 beersmith3
This sets my DPI settings to 0, changes the gtk-theme, runs a python script that changes my resolution and runs the program, and on program exit changes it back. This is working properly.
Now I want to change back my DPI settings to 136 on program exit
xfconf-query -c xsettings -p /Xft/DPI -s 136
My guess is I need to use a while loop but have no idea how to do it.
ch_resolution.py
#!/usr/bin/env python3
import argparse
import re
import subprocess
import sys
parser = argparse.ArgumentParser()
parser.add_argument('--output', required=True)
parser.add_argument('--resolution', required=True)
parser.add_argument('APP')
args = parser.parse_args()
device_context = '' # track what device's modes we are looking at
modes = [] # keep track of all the devices and modes discovered
current_modes = [] # remember the user's current settings
# Run xrandr and ask it what devices and modes are supported
xrandrinfo = subprocess.Popen('xrandr -q', shell=True, stdout=subprocess.PIPE)
output = xrandrinfo.communicate()[0].decode().split('\n')
for line in output:
# luckily the various data from xrandr are separated by whitespace...
foo = line.split()
# Check to see if the second word in the line indicates a new context
# -- if so, keep track of the context of the device we're seeing
if len(foo) >= 2: # throw out any weirdly formatted lines
if foo[1] == 'disconnected':
# we have a new context, but it should be ignored
device_context = ''
if foo[1] == 'connected':
# we have a new context that we want to test
device_context = foo[0]
elif device_context != '': # we've previously seen a 'connected' dev
# mode names seem to always be of the format [horiz]x[vert]
# (there can be non-mode information inside of a device context!)
if foo[0].find('x') != -1:
modes.append((device_context, foo[0]))
# we also want to remember what the current mode is, which xrandr
# marks with a '*' character, so we can set things back the way
# we found them at the end:
if line.find('*') != -1:
current_modes.append((device_context, foo[0]))
for mode in modes:
if args.output == mode[0] and args.resolution == mode[1]:
cmd = 'xrandr --output ' + mode[0] + ' --mode ' + mode[1]
subprocess.call(cmd, shell=True)
break
else:
print('Unable to set mode ' + args.resolution + ' for output ' + args.output)
sys.exit(1)
subprocess.call(args.APP, shell=True)
# Put things back the way we found them
for mode in current_modes:
cmd = 'xrandr --output ' + mode[0] + ' --mode ' + mode[1]
subprocess.call(cmd, shell=True)
edit:
Thanks #AndreLDM for pointing out that I do not need a separate python script to change the resolution, I don't know why I didn't think of that.
I changed it so I don't need the python script and it is working properly now. If I can improve this script please tell me!
#!/bin/bash
xrandr --output DP-0 --mode 2560x1440
xfconf-query -c xsettings -p /Xft/DPI -s 0
GTK_THEME=/usr/share/themes/Adwaita/gtk-2.0/gtkrc beersmith3
if [ $? == 0 ]
then
xrandr --output DP-0 --mode 3840x2160
xfconf-query -c xsettings -p /Xft/DPI -s 136
exit 0
else
xrandr --output DP-0 --mode 3840x2160
xfconf-query -c xsettings -p /Xft/DPI -s 136
exit 1
fi

Multiple Processes - Python

I am looking to run multiple instances of a command line script at the same time. I am new to this concept of "multi-threading" so am at bit of a loss as to why I am seeing the things that I am seeing.
I have tried to execute the sub-processing in two different ways:
1 - Using multiple calls of Popen without a communicate until the end:
command = 'raster2pgsql -I -C -e -s 26911 %s -t 100x100 -F p839.%s_image_sum_sum1 | psql -U david -d projects -h pg3' % (workspace + '\\r_sumsum1{}'.format(i), str(i))
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
command = 'raster2pgsql -I -C -e -s 26911 %s -t 100x100 -F p839.%s_image_sum_sum2 | psql -U david -d projects -h pg3' % (workspace + '\\r_sumsum2{}'.format(i), str(i))
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
command = 'raster2pgsql -I -C -e -s 26911 %s -t 100x100 -F p839.%s_image_sum_sum3 | psql -U david -d projects -h pg3' % (workspace + '\\r_sumsum3{}'.format(i), str(i))
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
(stdoutdata, stderrdata) = process.communicate()
this starts up each of the command line item but only completes the last entry leaving the other 2 hanging.
2 - Attempting to implement an example from Python threading multiple bash subprocesses? but nothing happens except for a printout of the commands (program hangs with no command line arguments running as observed in windows task manager:
import threading
import Queue
import commands
import time
workspace = r'F:\Processing\SM'
image = 't08r_e'
image_name = (image.split('.'))[0]
i = 0
process_image_tif = workspace + '\\{}{}.tif'.format((image.split('r'))[0], str(i))
# thread class to run a command
class ExampleThread(threading.Thread):
def __init__(self, cmd, queue):
threading.Thread.__init__(self)
self.cmd = cmd
self.queue = queue
def run(self):
# execute the command, queue the result
(status, output) = commands.getstatusoutput(self.cmd)
self.queue.put((self.cmd, output, status))
# queue where results are placed
result_queue = Queue.Queue()
# define the commands to be run in parallel, run them
cmds = ['raster2pgsql -I -C -e -s 26911 %s -t 100x100 -F p839.%s_image_sum_sum1 | psql -U david -d projects -h pg3' % (workspace + '\\r_sumsum1{}'.format(i), str(i)),
'raster2pgsql -I -C -e -s 26911 %s -t 100x100 -F p839.%s_image_sum_sum2 | psql -U david -d projects -h pg3' % (workspace + '\\r_sumsum2{}'.format(i), str(i)),
'raster2pgsql -I -C -e -s 26911 %s -t 100x100 -F p839.%s_image_sum_sum3 | psql -U david -d projects -h pg3' % (workspace + '\\r_sumsum3{}'.format(i), str(i)),
]
for cmd in cmds:
thread = ExampleThread(cmd, result_queue)
thread.start()
# print results as we get them
while threading.active_count() > 1 or not result_queue.empty():
while not result_queue.empty():
(cmd, output, status) = result_queue.get()
print(cmd)
print(output)
How can I run all of these commands at the same time achieving a result at the end? I am running in windows, pyhton 2.7.
My first try didn't work because of the repeated definitions of stdout and sterror. Removing these definitions causes expected behavior.

How to convert .rtp file(recorded using RTP Proxy codec G711) to .wav file

I need to convert a .rtp file (which has been recorded using RTP proxy) to .wav file.
If any one knows how it can be done, give me your solutions.
Thanks in advance:)
A little late to the party perhaps but I recently had the same problem and thought I should share my solution to it here if someone else has this question. I also used RTP-proxy to capture audio streams which were saved as two .rtp files, one for each channel, where .o. is the output of the one initiating the call (caller) and .a. is the one receiving the call (callee).
Solution 1.
RTP-proxy has a built in module which does the wav conversion for you called "extractaudio". The documentation is lacking to say the least but you can use it from the command-line as follows:
extractaudio -F wav -B /path/to/rtp /path/of/outfile.wav
This will convert one RTP file at a time to a WAV file. The module encode created WAV files with GSM-encoding. If this is undesired you can pass in -D pcm_16 as an extra argument to it to switch the encoding to Linear PCM 16, which is a much better format for retaining audio quality. I extracted WAV files this way programatically through python with the means of subprocesses in order to make command-line calls.
Solution 2.
You can extract the raw RTP data directly and convert it to a WAV file using a 3rd-part software like SoX or FFmpeg. This solution requires SoX, FFmpeg and tshark as dependencies. You could do without tshark if you opened the RTP file yourself and extracted the UDP data but it can be done easily with tshark.
Here is my code for it (Python 2.7.9):
import os
import subprocess
import shlex
import binascii
FILENAME = "my_file"
WORKING_DIR = os.path.dirname(os.path.realpath(__file__))
IN_FILE_O = "%s/%s.o.rtp" % (WORKING_DIR, FILENAME)
IN_FILE_A = "%s/%s.a.rtp" % (WORKING_DIR, FILENAME)
conversion_list = {"PCMU" : "sox -t ul -r 8000 -c 1 %s %s",
"GSM" : "sox -t gsm -r 8000 -c 1 %s %s" ,
"PCMA" : "sox -t al -r 8000 -c 1 %s %s",
"G722" : "ffmpeg -f g722 -i %s -acodec pcm_s16le -ar 16000 -ac 1 %s",
"G729": "ffmpeg -f g729 -i %s -acodec pcm_s16le -ar 8000 -ac 1 %s"
}
if __name__ == "__main__":
args_o = "tshark -n -r " + IN_FILE_O + " -T fields -e data"
args_a = "tshark -n -r " + IN_FILE_A + " -T fields -e data"
f_o = WORKING_DIR + "/" + "payload_o.g722"
f_a = WORKING_DIR + "/" + "payload_a.g722"
payload_o = subprocess.Popen(shlex.split(args_o), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True).communicate()[0]
payload_a = subprocess.Popen(shlex.split(args_a), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True).communicate()[0]
if os.path.exists(f_o):
os.remove(f_o)
if os.path.exists(f_a):
os.remove(f_a)
with open(f_o, "ab") as new_codec:
payload = payload_o.split("\n")
for line in payload:
line = line.rstrip()
tmp = "%s.o: " % FILENAME
for index, (op, code) in enumerate(zip(line[0::2], line[1::2])):
if index > 11:
new_codec.write(binascii.unhexlify(op + code))
with open(f_a, "ab") as new_codec:
payload = payload_a.split("\n")
for line in payload:
line = line.rstrip()
tmp = "%s.a: " % FILENAME
for index, (op, code) in enumerate(zip(line[0::2], line[1::2])):
if index > 11:
new_codec.write(binascii.unhexlify(op + code))
owav = WORKING_DIR + "/" + "%s.o.wav" % FILENAME
awav = WORKING_DIR + "/" + "%s.a.wav" % FILENAME
if os.path.exists(owav):
os.remove(owav)
if os.path.exists(awav):
os.remove(awav)
print("Creating %s with %s" % (owav, f_o))
print("Creating %s with %s" % (awav, f_a))
subprocess.Popen(shlex.split(conversion_list["G722"] % (f_o, owav)), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True).communicate()[0]
subprocess.Popen(shlex.split(conversion_list["G722"] % (f_a, awav)), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True).communicate()[0]
I have G722 hardcoded as input data in my solution but it should work with any type of input encoding given you had the correct SoX/FFmpeg command for it. I've added a few different encodings in a predefined dict. The drawback with this solution is that you have to know the encoding of the call recorded in the RTP file. I tried to find an equivalent parameter in the RTP file to the rtp.p_type found in PCAP files which entails the codec used but didn't have any luck. I'm not familiar enough with RTP files though so it might be present in the data somewhere. Another drawback of this is that the produced audio files can sometimes be shorter than the original audio. I'm assuming this is due to Silence Suppression in which case it could be fixed by inserting silence yourself at the places where the timestamps indicate silence has been removed (not transmitted).
A great way to view information about RTP files is through the tshark-command:
tshark -n -r /path/to/file.rtp
Hope it will help someone!
EDIT:
I found another question about detecting the encoding within a RTP file.

Notepad++ vertical block select copy paste not retained across clips

I'm using Notepad++ to vertically select and copy blocks of text. Pasting the latest block of text (that is currently in the clipboard buffer) works fine, however going back to the second and third previous clipboard buffers (which were originally copied as blocks) does not paste these other buffers as blocks, but rather as a first line followed by newline, second line newline, etc, etc.
For example, suppose I block copy the following block
test
test
test
The latest clipboard buffer pastes as
test
test
test
assuming the cursor is 4 spaces indented.
However, if the latest clipboard buffer is moved to the second place in the clipboard buffer queue, I get the following paste:
test
test
test
I'm using ClipMate to store previous clipboard buffers.
Why does notepad++ know to block-paste the latest clipboard text data (copied as a block) but not the second to last clipboard buffer?
Is there a way to store a clipboard clips' block state?
It looks like Notepad++ is pasting from an internal buffer, and not taking the data from the clipboard. There IS a private data format called MSDEVColumnSelect, but if I try to force ClipMate to capture it, the data is empty. So this seems to be a case where the application is playing smoke-and-mirrors games with copy/paste, and it's not really a clipboard feature at all.
I've written a solution using the Python Script Scintilla wrapper notepad++ plugin.
Use this for copy.
Save as C:\Program Files\Notepad++\plugins\PythonScript\scripts\Samples\Copy.py
Map to shortcuts Ctrl+c and Ctrl+INS
# $Revision: 1.2 $
# $Author: dot $
# $Date: 2012/03/23 20:59:46 $
from Npp import *
import string
# First we'll start an undo action, then Ctrl+z will undo the actions of the whole script
editor.beginUndoAction()
if editor.getSelText() != '':
strClip = ""
if editor.selectionIsRectangle():
strClip = "<vertical>"+editor.getSelText()+"</vertical>"
else:
strClip = editor.getSelText()
editor.copyText(strClip)
# End the undo action, so Ctrl+z will undo the above two actions
editor.endUndoAction()
Use this for cut.
Save as C:\Program Files\Notepad++\plugins\PythonScript\scripts\Samples\Cut.py
Map to shortcuts Ctrl+x and Shift+DEL
# $Revision: 1.2 $
# $Author: dot $
# $Date: 2012/03/23 20:59:46 $
from Npp import *
import string
# First we'll start an undo action, then Ctrl+z will undo the actions of the whole script
editor.beginUndoAction()
if editor.getSelText() != '':
strClip = ""
if editor.selectionIsRectangle():
strClip = "<vertical>"+editor.getSelText()+"</vertical>"
else:
strClip = editor.getSelText()
editor.copyText(strClip)
editor.clear()
# End the undo action, so Ctrl+z will undo the above two actions
editor.endUndoAction()
Now download pyperclip.py to C:\Program Files\Notepad++\plugins\PythonScript\lib
Use this for paste.
Save as C:\Program Files\Notepad++\plugins\PythonScript\scripts\Samples\Paste.py
Map to shortcuts Ctrl+v and Shift+INS
# $Revision: 1.11 $
# $Author: dot $
# $Date: 2012/05/18 22:22:22 $
from Npp import *
import pyperclip
import string
#debug = True
debug = False
# First we'll start an undo action, then Ctrl-z will undo the actions of the whole script
editor.beginUndoAction()
# Get the clip
clip = pyperclip.getcb()
# Debug
if debug:
bufferID = notepad.getCurrentBufferID()
# Show console for debugging
console.clear()
console.show()
console.write( "editor.getRectangularSelectionCaret() = " + str(editor.getRectangularSelectionCaret() ) + "\n")
console.write( "editor.getRectangularSelectionAnchor() = " + str(editor.getRectangularSelectionAnchor()) + "\n")
console.write( "editor.getSelectionStart() = " + str(editor.getSelectionStart() ) + "\n")
console.write( "editor.getSelectionEnd() = " + str(editor.getSelectionEnd() ) + "\n")
console.write( "editor.getCurrentPos() = " + str(editor.getCurrentPos() ) + "\n")
console.write( "editor.getAnchor() = " + str(editor.getAnchor() ) + "\n")
console.write( "editor.getRectangularSelectionAnchorVirtualSpace() = " + str(editor.getRectangularSelectionAnchorVirtualSpace()) + "\n")
console.write( "editor.getRectangularSelectionCaretVirtualSpace() = " + str(editor.getRectangularSelectionCaretVirtualSpace() ) + "\n")
console.write( "editor.getSelectionNCaretVirtualSpace(0) = " + str(editor.getSelectionNCaretVirtualSpace(0) ) + "\n")
console.write( "editor.getSelectionNAnchorVirtualSpace(0) = " + str(editor.getSelectionNAnchorVirtualSpace(0) ) + "\n")
if editor.getRectangularSelectionCaret() == -1 and \
editor.getRectangularSelectionAnchor() == -1 and \
editor.getSelectionStart() == 0 and \
editor.getSelectionEnd() == 0 and \
editor.getCurrentPos() == 0 and \
editor.getAnchor() == 0 and \
editor.getRectangularSelectionAnchorVirtualSpace() == 0 and \
editor.getRectangularSelectionCaretVirtualSpace() == 0 and \
editor.getSelectionNCaretVirtualSpace(0) == 0 and \
editor.getSelectionNAnchorVirtualSpace(0) == 0:
currentPos = editor.getCurrentPos()
# Debug
if debug:
console.write( "state 0\n")
if editor.getRectangularSelectionCaret() != 0 and editor.getRectangularSelectionAnchor() != 0:
if editor.getSelectionStart() == editor.getRectangularSelectionCaret() and \
editor.getSelectionEnd() == editor.getRectangularSelectionAnchor():
# Debug
if debug:
console.write( "state 1\n" )
currentPos = min(editor.getRectangularSelectionCaret(),editor.getRectangularSelectionAnchor())
elif editor.getSelectionStart() < editor.getRectangularSelectionCaret():
# Debug
if debug:
console.write( "state 2\n")
currentPos = editor.getSelectionStart()
elif editor.getSelectionStart() == editor.getRectangularSelectionCaret() and \
editor.getSelectionEnd() > editor.getRectangularSelectionAnchor():
currentPos = min(editor.getRectangularSelectionCaret(),editor.getRectangularSelectionAnchor())
# Debug
if debug:
console.write( "state 3\n")
elif editor.getCurrentPos() != 0 and editor.getAnchor() != 0:
# Debug
if debug:
console.write( "state 4\n")
currentPos = min(editor.getCurrentPos(),editor.getAnchor())
elif editor.getSelectionStart() == editor.getRectangularSelectionCaret() and \
editor.getSelectionEnd() > editor.getRectangularSelectionAnchor():
# Debug
if debug:
console.write( "state 5\n")
currentPos = min(editor.getRectangularSelectionCaret(),editor.getRectangularSelectionAnchor())
else:
currentPos = editor.getCurrentPos()
# Debug
if debug:
console.write( "state 6\n")
# Debug
if debug:
console.write( "currentPos = " + str(currentPos) + "\n")
if editor.getRectangularSelectionAnchorVirtualSpace() != editor.getRectangularSelectionCaretVirtualSpace() and \
( editor.getRectangularSelectionAnchorVirtualSpace() == editor.getSelectionNCaretVirtualSpace(0) and \
editor.getSelectionNCaretVirtualSpace(0) == editor.getSelectionNAnchorVirtualSpace(0) ):
prefix = editor.getRectangularSelectionCaretVirtualSpace()
# Debug
if debug:
console.write( "state 7\n")
else:
prefix = min(editor.getSelectionNCaretVirtualSpace(0),editor.getSelectionNAnchorVirtualSpace(0))
# Debug
if debug:
console.write( "state 8\n")
# Debug
if debug:
console.write( "prefix = " + str(prefix) + "\n")
prefixSpaces = "".ljust(prefix,' ')
eolmode = editor.getEOLMode()
# SC_EOL_CRLF (0), SC_EOL_CR (1), or SC_EOL_LF (2)
if eolmode == 0:
eol = "\r\n"
eolcnt = 2
elif eolmode == 1:
eol = '\r'
eolcnt = 1
elif eolmode == 2:
eol = "\n"
eolcnt = 1
if prefix > 0:
if currentPos < editor.getCurrentPos():
editor.insertText(editor.getLineEndPosition(editor.lineFromPosition(currentPos)),prefixSpaces)
editor.gotoPos(editor.getLineEndPosition(editor.lineFromPosition(currentPos+prefix)))
start = currentPos+prefix
# Debug
if debug:
console.write( "state 9\n")
else:
editor.insertText(editor.getLineEndPosition(editor.lineFromPosition(editor.getCurrentPos())),prefixSpaces)
editor.gotoPos(editor.getLineEndPosition(editor.lineFromPosition(editor.getCurrentPos())))
start = editor.getCurrentPos()
# Debug
if debug:
console.write( "state 10\n")
else:
start = currentPos
# Debug
if debug:
console.write( "state 11\n")
# Debug
if debug:
console.write( "start = " + str(start) + "\n")
if clip != "":
if editor.getSelectionStart() != editor.getSelectionEnd() and \
( editor.getColumn(editor.getSelectionStart()) != editor.getColumn(editor.getSelectionEnd()) or \
( editor.getColumn(editor.getSelectionStart()) == editor.getColumn(editor.getSelectionEnd()) and \
editor.getColumn(editor.getSelectionStart()) == 0 ) ) and \
prefix == 0:
editor.clear()
# Debug
if debug:
console.write( "state 12\n")
# We are dealing with a vertical paste
if clip.startswith("<vertical>") and clip.endswith("</vertical>"):
clip = clip[10:-11]
startCol = editor.getColumn(start)
startRow = editor.lineFromPosition(start)
# Debug
if debug:
console.write( "startCol = " + str(startCol) + "\n")
# Debug
if debug:
console.write( "startRow = " + str(startRow) + "\n")
# keepends = False
clipSplit = clip.splitlines(False)
clipSplitLen = len(clipSplit)
for index,line in enumerate(clipSplit):
if index == 0:
localPrefixSpaces = ""
elif index == (clipSplitLen-1):
localPrefixSpaces = prefixSpaces
else:
localPrefixSpaces = prefixSpaces
try:
editorLine = editor.getLine(startRow+index).strip(eol)
editorLineLen = len(editorLine)
# Empty line
if editorLineLen == 0:
editor.insertText(editor.positionFromLine(startRow+index),"".ljust(startCol,' '))
editor.insertText(editor.findColumn(startRow+index,startCol),line)
else:
if editorLineLen < startCol:
editor.insertText(editor.getLineEndPosition(startRow+index),"".ljust(startCol-editorLineLen,' '))
editor.insertText(editor.findColumn(startRow+index,startCol),line)
# End of file
except IndexError:
editor.documentEnd()
editor.appendText(eol)
editor.appendText("".ljust(startCol,' ') + line)
editor.setCurrentPos(start)
editor.setSelection(start,start)
# We are dealing with a horizontal paste
else:
editor.insertText(start, clip)
editor.setCurrentPos(start + len(clip))
editor.setSelection(start + len(clip),start + len(clip))
# End the undo action, so Ctrl-z will undo the above two actions
editor.endUndoAction()
# Debug
if debug:
notepad.activateBufferID(bufferID)
This assumes that VirtualSpaceOptions are set to 3.
Modify file C:\projects\misc\PythonScriptNppPlugin\startup.py to the following
code below and ensure it runs on every notepad++ start.
# $Revision: 1.2 $
# $Author: dot $
# $Date: 2012/03/23 20:59:46 $
# The lines up to and including sys.stderr should always come first
# Then any errors that occur later get reported to the console
# If you'd prefer to report errors to a file, you can do that instead here.
import sys
from Npp import *
# Set the stderr to the normal console as early as possible, in case of early errors
sys.stderr = console
# Define a class for writing to the console in red
class ConsoleError:
def __init__(self):
global console
self._console = console;
def write(self, text):
self._console.writeError(text);
def flush(self):
pass
# Set the stderr to write errors in red
sys.stderr = ConsoleError()
# This imports the "normal" functions, including "help"
import site
# See docs
# http://npppythonscript.sourceforge.net/docs/latest/intro.html
# http://npppythonscript.sourceforge.net/docs/latest/scintilla.html
def set_word_chars(args):
# Enable the virtual space options for both Scintilla views
# For more information, see the Scintilla documentation on virtual space and the SCI_SETVIRTUALSPACEOPTIONS message.
editor.setVirtualSpaceOptions(3)
# Set the word characters
editor.setWordChars('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$')
notepad.callback(set_word_chars, [NOTIFICATION.BUFFERACTIVATED])
# This sets the stdout to be the currently active document, so print "hello world",
# will insert "hello world" at the current cursor position of the current document
sys.stdout = editor
editor.setVirtualSpaceOptions(3)
# Set the word characters
editor.setWordChars('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$')
#console.show()

Resources