I am trying to filter a wireshark capture that contains sdp information. The information can appear multiple times in the same packet, I am trying to filter on only the initial value.
As a more concrete example the sdp.media.port attribute may be present multiple times in the same packet with different values, for example first as 12004 for audio and then as 12006 for image. Setting a filter of either sdp.media.port == 12004 or sdp.media.port == 12006 will select this packet.
What is the syntax for a filter to only select packets that have 12006 as the initial value? This filter would ignore the above packet if set to 12006, but would select this packet if set to 12004
If I understand you correctly, you want to select the packets, where Media Type: audio contains the value 12004.
In that case you can use the following display filter:
(sdp.media.media == "audio") && (sdp.media.port == 12004)
BTW
You can use TShark to create a list:
Only first occurrence:
tshark -r test.pcap -Y sdp.media.port -T fields -e frame.number -e sdp.media.media -e sdp.media.port -E occurrence=f
3 audio 5004
6 audio 23010
All occurrences:
tshark -r test.pcap -Y sdp.media.port -T fields -e frame.number -e sdp.media.media -e sdp.media.port -E occurrence=a
3 audio,video 5004,5006
6 audio,video 23010,23030
You can find more information about TShark at the man-page.
Related
I need to split a video into many smaller videos.
I have tried PySceneDetect and its 2 scene detection methods don't fit my need.
The idea is to trigger a scene cut/break every time the volume is very low, every time audio level is less than a given parameter. I think overall RMS dB volume level is what I mean.
The purpose is to split an mp4 video into many short videos, each smaller video with short dialog phrases.
So far I have a command to get the overall RMS audio volume level.
ffprobe -f lavfi -i amovie=01x01TheStrongestMan.mp4,astats=metadata=1:reset=1 -show_entries frame=pkt_pts_time:frame_tags=lavfi.astats.Overall.RMS_level,lavfi.astats.1.RMS_level,lavfi.astats.2.RMS_level -of csv=p=0
How can I get only the minimum values for RMS level and its corresponding frame or time?
And then how can I use ffmpeg to split the video in many videos on every frame that corresponds to a minimum RMS?
Thanks.
Use silencedetect audio filter and feed its debugging output to segment output format parameter.
Here is a ready-made script:
#!/bin/bash
IN=$1
OUT=$2
true ${SD_PARAMS:="-55dB:d=0.3"};
true ${MIN_FRAGMENT_DURATION:="20"};
export MIN_FRAGMENT_DURATION
if [ -z "$OUT" ]; then
echo "Usage: split_by_silence.sh input_media.mp4 output_template_%03d.mkv"
echo "Depends on FFmpeg, Bash, Awk, Perl 5. Not tested on Mac or Windows."
echo ""
echo "Environment variables (with their current values):"
echo " SD_PARAMS=$SD_PARAMS Parameters for FFmpeg's silencedetect filter: noise tolerance and minimal silence duration"
echo " MIN_FRAGMENT_DURATION=$MIN_FRAGMENT_DURATION Minimal fragment duration"
exit 1
fi
echo "Determining split points..." >& 2
SPLITS=$(
ffmpeg -nostats -v repeat+info -i "${IN}" -af silencedetect="${SD_PARAMS}" -vn -sn -f s16le -y /dev/null \
|& grep '\[silencedetect.*silence_start:' \
| awk '{print $5}' \
| perl -ne '
our $prev;
INIT { $prev = 0.0; }
chomp;
if (($_ - $prev) >= $ENV{MIN_FRAGMENT_DURATION}) {
print "$_,";
$prev = $_;
}
' \
| sed 's!,$!!'
)
echo "Splitting points are $SPLITS"
ffmpeg -v warning -i "$IN" -c copy -map 0 -f segment -segment_times "$SPLITS" "$OUT"
You specify input file, output file template, silence detection parametres and minimum fragment size, it writes multiple files.
Silence detection parameters may need to be tuned:
SD_PARAMS environment variable contains two parameters: noise tolerance level and minimum silence duration. Default value is -55dB:d=0.3.
Decrease the -55dB to e.g. -70dB if some faint non-silent sounds trigger spitting when they should not. Increase it to e.g. -40dB if it does not split on silence because of there is some noise in it, making it not completely silent.
d=0.3 is a minimum silence duration to be considered as a splitting point. Increase it if only serious (e.g. whole 3 seconds) silence should be considered as real, split-worthy silence.
Another environment variable MIN_FRAGMENT_DURATION defines amount of time silence events are ignored after each split. This sets minimum fragment duration.
The script would fail if no silence is detected at all.
There is a refactored version on Github Gist, but there was a problem with it for one user.
This question already has answers here:
Bash and sort files in order
(8 answers)
Closed 7 years ago.
I have 3 webcams set up in a building, uploading still images to a webserver. I'm using ffmpeg to encode the jpgs to mp4 video.
The directories are set up like this:
Cam1/201504
Cam1/201505
Cam2/201504
Cam2/201505
Cam3/201504
Cam3/201505
I'm using the following bash loop/ffmpeg parameters to make one video per camera, per year. This works well so far (well... except that my SSD is rapidly degrading in performance - too many simultaneous read/write operations?):
find Cam2/2013* -name "*.jpg" -print0 | xargs -0 cat | ffmpeg -f image2pipe -framerate 30 -vcodec mjpeg -i - -vcodec libx264 -profile:v baseline -level 3.0 -movflags +faststart -crf 19 -pix_fmt yuv420p -r 30 "Cam2-2013-30fps-19crf.mp4"
The individual files are named like this (confusing ffmpeg's built-in file sequencer):
Cam1_2015052413543201.jpg
Cam1_2015052413544601.jpg
Cam2_2015052413032601.jpg
Cam2_2015052413544901.jpg
I now need to create one video for an entire year across all 3 cameras, ordered by timestamp. To accomplish this, I need to sort the find results by the segment of the filename after the underscore.
What do I pipe the find output to to accomplish this? For example, the files above would be ordered like this:
Cam2_2015052413032601.jpg
Cam1_2015052413543201.jpg
Cam1_2015052413544601.jpg
Cam2_2015052413544901.jpg
Any help is very much appreciated!
sort
sort -t '_' -nk2
-t '_' # specifices that the field seperator should be an underscore
-nk2 # start sorting from the second field (after the underscore)..n sort according to numerical value/timestamp
output
Cam2_2015052413032601.jpg
Cam1_2015052413543201.jpg
Cam1_2015052413544601.jpg
Cam2_2015052413544901.jpg
pipe sort to find command like
sort -t '_' -nk2 --files0-from=-
Use sort with the --key option. See your man page of sort for details of the key format. Generally (for both coreutils and BSD sort) it should be F[.C][OPTS][,F[.C][OPTS]], where F is for field and C is for character position. Here you want to sort from the 5th character of the first field, so --key=1.5 will do:
> echo -e 'Cam1_2015052413543201.jpg\nCam1_2015052413544601.jpg\nCam2_2015052413032601.jpg\nCam2_2015052413544901.jpg' | sort --key=1.5
Cam2_2015052413032601.jpg
Cam1_2015052413543201.jpg
Cam1_2015052413544601.jpg
Cam2_2015052413544901.jpg
Here you seem to have not only basenames in the output of find, but relative paths with path segments like Cam1/201505/ prepended, but you can still count the number of characters and hence write the appropriate keydef. For instance, say the paths for the images in the example above are
Cam1/201505/Cam1_2015052413543201.jpg
Cam1/201505/Cam1_2015052413544601.jpg
Cam2/201505/Cam2_2015052413032601.jpg
Cam2/201505/Cam2_2015052413544901.jpg
Then
sort --key=1.17
will give you the correct order
Cam2/201505/Cam2_2015052413032601.jpg
Cam1/201505/Cam1_2015052413543201.jpg
Cam1/201505/Cam1_2015052413544601.jpg
Cam2/201505/Cam2_2015052413544901.jpg
I'm making a script to auto-generate a url with a random number at a specific location. This will be for calling a JSON API for a random endpoint. The end goal is to generate something like this:
curl -s http://api.openbeerdatabase.com/v1/beers/<RAND_INT>.json | jq '.'
where <RAND_INT> is a randomly-generated number. I can create this random number with the following command:
$ od -An -N2 -i /dev/random
126
I do not know why the 10 extra spaces are in the output. When I chain the above commands together to generate the URL, I get this:
$ echo http://api.openbeerdatabase.com/v1/beers/`od -An -N2 -i /dev/random`.json
http://api.openbeerdatabase.com/v1/beers/ 43250.json
As you see, there is a single extra space in the generated URL. How do I avoid this?
I've also tried subshelling the rand_int command $(od -An -N2 -i /dev/random) but that produces the same thing. I've thought about piping the commands together, but I don't know how to capture the output of the rand_int command in a variable to be used in the URL.
As the comments show, there's more than one way to do this. Here's what I would do:
(( n = $( od -An -N2 -i /dev/urandom ) ))
echo http://api.openbeerdatabase.com/v1/beers/${n}.json
Or, to put it in one line:
echo http://api.openbeerdatabase.com/v1/beers/$(( $( od -An -N2 -i /dev/urandom ) )).json
Or, just use ${RANDOM} instead, since bash provides it, although its values top out at 32767, which might be one reason you preferred your od-based method.
Got the following from FFmpeg FAQ:
mkfifo intermediate1.mpg
mkfifo intermediate2.mpg
ffmpeg -i input1.avi -sameq -y intermediate1.mpg < /dev/null &
ffmpeg -i input2.avi -sameq -y intermediate2.mpg < /dev/null &
cat intermediate1.mpg intermediate2.mpg |\
ffmpeg -f mpeg -i - -sameq -vcodec mpeg4 -acodec libmp3lame output.avi
Before i use or modify it I would like to understand it completely.
What does the < /dev/null & do?
I understand | is pipe but why |\ ?
What is the -f mpeg after ffmpeg (Seems, it tells ffmpeg to accept the piped in output from the cat(?) )
< /dev/null &
This is actually two parts:
< /dev/null
&
1 (< /dev/null) is just a simple way to pass no input/EOF to a program. I'm not sure it's needed but it may be because you are using named pipes.
2 (&) simply pushes the command to the background and allows you to do other things. This is necessary because otherwise, ffmpeg would just sit there waiting for the other end of the named pipe to "open".
Backslash after pipe
The backslash after the pipe is simply there to allow you to enter the long command on multiple lines. If you want to write it on a single line, you should omit the backslash. You'll notice that the prompt changes from your usual [user#machine directory]$ (or whatever) to something like > after you enter the first line (ending with a backslash). This signifies that your command is being continued from an earlier line.
ffmpeg -f switch
The man page for ffmpeg indicates that the -f switch allows you to force a file format. In the example in the FAQ, you want to force an input format (read: tell ffmpeg what input format to expect) since your using piped bits as input. Usually, it would try to guess the input format based on the file extension and/or "file magic".
Tshark is a command line packet sniffer. I am trying to find a way to get information from the packets, put it in a variable and do some regular expression on it.
Right now, I am getting this from tshark:
Capturing on eth0
0.000000 74.125.71.116 -> 112.204.184.111 TCP http > 55828 [ACK] Seq=1 Ack=1 Win=6434 Len=0 TSV=2558834852 TSER=542043
0.000035 112.204.184.111 -> 74.125.71.116 HTTP Continuation or non-HTTP traffic
0.000043 112.204.184.111 -> 74.125.71.116 HTTP Continuation or non-HTTP traffic
Note: I am using Ruby.
You can use tshark itself without another utility. This command prints out all URI's from packets as they arrive:
$ tshark -R http.request.full_uri -T fields -e http.request.full_uri -i en0
You can refine the display filter (the -R parameter) to better match your requirements. It even supports Perl regular expression matching:
# Mac OS X
$ tshark -R 'http.request.full_uri matches "\\.jpg\|\\.js"' -T fields -e http.request.full_uri -i en0
Example output from visiting youtube.com:
$ tshark -R 'http.request.full_uri matches "\\.jpg\|\\.js"' -T fields -e http.request.full_uri -i en0
Capturing on en0
http://s.ytimg.com/yt/jsbin/www-core-vfl3_mVgh.js
http://s.ytimg.com/yt/jsbin/www-subscriptions-vfl5HwfxW.js
http://i2.ytimg.com/i/QMbqH7xJu5aTAPQ9y_U7WQ/1.jpg?v=95416b
http://i1.ytimg.com/vi/4R0BAjrZqyY/default.jpg
http://i4.ytimg.com/i/KVtW8ExxO21F2sNLtwrq_w/1.jpg?v=a1fa0c
http://i3.ytimg.com/vi/z3U0udLH974/default.jpg
http://i2.ytimg.com/vi/arKyyDRsE_8/default.jpg
http://i2.ytimg.com/vi/y1TGz-fEyiE/default.jpg
http://i2.ytimg.com/vi/-tc983PZK3o/default.jpg
http://i2.ytimg.com/vi/1yT2rrTyMK8/default.jpg
http://i4.ytimg.com/vi/cciUXpITsu0/default.jpg
http://i2.ytimg.com/vi/uG0dimAxHpI/default.jpg
http://i2.ytimg.com/vi/eP9P50kbzTk/default.jpg
http://i1.ytimg.com/vi/ppBe0T412uU/default.jpg
http://i1.ytimg.com/vi/8360wVLtEuk/default.jpg
http://i4.ytimg.com/vi/G_yB7wdTxa0/default.jpg
http://i4.ytimg.com/vi/gcZxoLs3NIU/default.jpg
http://i1.ytimg.com/i/po2fJvnalYlwN97ehhyfBQ/1.jpg?v=b8e52a
http://i1.ytimg.com/vi/D2Xjj_ra8lQ/default.jpg
http://i1.ytimg.com/vi/PewewGu9gp8/default.jpg
http://i1.ytimg.com/vi/P9FkRD6ppGo/default.jpg
http://i3.ytimg.com/vi/vpZ4SMU4znQ/default.jpg
http://i3.ytimg.com/vi/jrrSGulNOLc/default.jpg
http://i3.ytimg.com/vi/FJtTzQfdnoQ/default.jpg
http://i3.ytimg.com/vi/68sEHPpQXes/default.jpg
http://i2.ytimg.com/vi/iWYqsaJk_U8/default.jpg
http://i4.ytimg.com/vi/7Prb8DbdfwY/default.jpg
http://i1.ytimg.com/vi/HJFlxLJSX8E/default.jpg
http://i1.ytimg.com/vi/ta6Vu_v7VLg/default.jpg
http://i1.ytimg.com/vi/Hq7NtDSIErE/default.jpg
http://i4.ytimg.com/vi/Sjdj7qhcTuw/default.jpg
http://i3.ytimg.com/vi/Nm3Acf3_oMY/default.jpg
http://i3.ytimg.com/vi/BpsrThXh_gM/default.jpg
http://i3.ytimg.com/vi/Z3yapgewktY/default.jpg
http://i3.ytimg.com/vi/2UFc1pr2yUU/default.jpg
http://i2.ytimg.com/vi/q_Bt6NwD4FY/default.jpg
http://i2.ytimg.com/vi/uTAAlzABzBA/default.jpg
http://i2.ytimg.com/vi/iRLUY6dMF8k/default.jpg
http://i2.ytimg.com/vi/-cDH6CYzTAw/default.jpg
http://i1.ytimg.com/vi/8p6Fn8R1Rc4/default.jpg
http://i1.ytimg.com/vi/T8gDQWdlW6A/default.jpg
http://i2.ytimg.com/vi/ERTcZV7uTFU/default.jpg
http://i1.ytimg.com/vi/PyxgwA6PvnI/default.jpg
http://i1.ytimg.com/vi/xUGlezOCvu4/default.jpg
http://i1.ytimg.com/vi/Ljb6Mne8Mfc/default.jpg
Note: In Windows, I've seentshark print all URIs in a particular packet in one line without delimiters (e.g., "http://www.google.comhttp://www.google.com/logos/classicplus.png"). Only some packets were affected by this.
You could either pipe this data into a file which you then open and parse with Ruby, or you could use a Ruby lib that can access the same data, such as: http://sourceforge.net/apps/trac/rubypcap/