Saving video from Flash Player 10.2 or unlink is not a hindrance to us
I, like probably many other Linux users, used to save videos from sites like YouTube by copying temporary files created by Adobe Flash. Like that:
Having put a fresh pre-release of a flash player, which was recently discussed on the hub (I have a 64-bit system), I was surprised to find that this method no longer works, since no files are created in the temporary directory. Having reasoned, however, that the player hardly stores the entire video in memory, and somewhere he still needs to write it, I started an investigation.
... That is, I decided to see the list of files opened by the plugin. First, we need the PID of the process in which the plugin is hosted. I use Firefox, so we’ll simply search:
As you can see, Mozilla runs the plugin in a separate process and its PID is 10099. Now you can see the list of open files with the command
All the most interesting things turned out to be at the end and right before my eyes, but for the sake of order, let’s try to filter out regular files opened by the process. This can probably be done with built-in tools
It immediately became clear where our temporary file went : the plugin removed ( unlink ) the link to the file from the directory, but left its descriptor open. Thus, the file ceased to be visible in the file system, but did not disappear, and it will be permanently deleted only when the last handle that refers to it closes.
But how do we now get the contents of a file opened by only one process? Very simple using the procfs file system . The directory
(Here, by the way, is another way to view files opened by the process, in addition to
And, although readlink returns the names of nonexistent files for some of these links, you can safely read from them (if permissions allow), which we will use:
That's all. These are quite trivial things (many, I think, have guessed what will be discussed from the heading alone), but, I hope, for someone this simple trick will be useful.
UPD
kreon designed these actions as a script (I allowed myself to modify it a bit by adding an argument):
Using:
UPD 2
In the comments, they repeatedly pointed to the irrationality of this method and in return offered a variety of browser programs and plugins for downloading videos. Of course, for downloading from YouTube it will be more convenient to use them (although you still need to see if they have the ability to get video from the browser cache because of the above). However, all these plugins are sharpened on a specific, albeit a fairly large, list of video hosting sites. This method also allows you to get video almost always if the video is downloaded via HTTP, and RTMP streaming is not used.
$ cp /tmp/FlashIBmQCU video.flv
Having put a fresh pre-release of a flash player, which was recently discussed on the hub (I have a 64-bit system), I was surprised to find that this method no longer works, since no files are created in the temporary directory. Having reasoned, however, that the player hardly stores the entire video in memory, and somewhere he still needs to write it, I started an investigation.
... That is, I decided to see the list of files opened by the plugin. First, we need the PID of the process in which the plugin is hosted. I use Firefox, so we’ll simply search:
$ ps x | grep firefox
9800 ? S 0:00 /bin/sh /usr/lib/firefox-3.6.9/firefox
9805 ? S 0:00 /bin/sh /usr/lib/firefox-3.6.9/run-mozilla.sh /usr/lib/firefox-3.6.9/firefox-bin
9809 ? Sl 14:58 /usr/lib/firefox-3.6.9/firefox-bin
10099 ? Sl 4:10 /usr/lib/firefox-3.6.9/plugin-container /usr/lib/mozilla/plugins/libflashplayer.so 9809 plugin
26199 pts/13 S+ 0:00 grep firefox
As you can see, Mozilla runs the plugin in a separate process and its PID is 10099. Now you can see the list of open files with the command
lsof
:$ lsof -p 10099
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
# поскипано 152 строки
plugin-co 10099 rooslan mem REG 8,21 26048 2656 /usr/lib/gconv/gconv-modules.cache
plugin-co 10099 rooslan mem REG 8,21 343 106080 /usr/lib/locale/ru_RU.utf8/LC_IDENTIFICATION
plugin-co 10099 rooslan 0r CHR 1,3 3419 /dev/null
plugin-co 10099 rooslan 1w FIFO 0,6 9649 pipe
plugin-co 10099 rooslan 2w FIFO 0,6 9649 pipe
plugin-co 10099 rooslan 3u unix 0xffff88007304a3c0 287192 socket
plugin-co 10099 rooslan 4r 0000 0,7 0 32 anon_inode
plugin-co 10099 rooslan 5w unix 0xffff8800c5425e40 287277 socket
plugin-co 10099 rooslan 6r unix 0xffff8800c5424b00 287278 socket
plugin-co 10099 rooslan 7w FIFO 0,6 287279 pipe
plugin-co 10099 rooslan 8r FIFO 0,6 287279 pipe
plugin-co 10099 rooslan 9w FIFO 0,6 287280 pipe
plugin-co 10099 rooslan 10u FIFO 0,6 287280 pipe
plugin-co 10099 rooslan 11u FIFO 0,6 287281 pipe
plugin-co 10099 rooslan 12u FIFO 0,6 287281 pipe
plugin-co 10099 rooslan 13u unix 0xffff88007304a100 287284 socket
plugin-co 10099 rooslan 14u REG 8,24 376832 1409239 /home/rooslan/.mozilla/firefox/xxxxxxxx.default/cert8.db
plugin-co 10099 rooslan 15w REG 8,24 16384 1409240 /home/rooslan/.mozilla/firefox/xxxxxxxx.default/key3.db
plugin-co 10099 rooslan 16u REG 8,23 494641 16 /tmp/FlashXXlm7mcU (deleted)
plugin-co 10099 rooslan 17u FIFO 0,6 404625 pipe
plugin-co 10099 rooslan 18u FIFO 0,6 404625 pipe
plugin-co 10099 rooslan 19r FIFO 0,6 404626 pipe
plugin-co 10099 rooslan 20w FIFO 0,6 404626 pipe
plugin-co 10099 rooslan 21r unix 0xffff880015a2b9c0 404630 socket
All the most interesting things turned out to be at the end and right before my eyes, but for the sake of order, let’s try to filter out regular files opened by the process. This can probably be done with built-in tools
lsof
, but the dimensions man lsof
quickly discourage the desire to read it to solve such a passing problem. Therefore, I preferred to use a simple filter on AWK:$ lsof -p 10099 | awk '$4 ~ /^[0-9]+/ && $5 == "REG"'
plugin-co 10099 rooslan 14u REG 8,24 376832 1409239 /home/rooslan/.mozilla/firefox/xxxxxxxx.default/cert8.db
plugin-co 10099 rooslan 15w REG 8,24 16384 1409240 /home/rooslan/.mozilla/firefox/xxxxxxxx.default/key3.db
plugin-co 10099 rooslan 16u REG 8,23 494641 16 /tmp/FlashXXlm7mcU (deleted)
It immediately became clear where our temporary file went : the plugin removed ( unlink ) the link to the file from the directory, but left its descriptor open. Thus, the file ceased to be visible in the file system, but did not disappear, and it will be permanently deleted only when the last handle that refers to it closes.
But how do we now get the contents of a file opened by only one process? Very simple using the procfs file system . The directory
/proc/$PID/fd
contains symbolic links to all descriptors opened by the PID process .$ ls -l /proc/10099/fd
итого 0
lr-x------ 1 rooslan rooslan 64 2010-09-16 23:56 0 -> /dev/null
l-wx------ 1 rooslan rooslan 64 2010-09-16 23:56 1 -> pipe:[9649]
lrwx------ 1 rooslan rooslan 64 2010-09-16 23:56 10 -> pipe:[287280]
lrwx------ 1 rooslan rooslan 64 2010-09-16 23:56 11 -> pipe:[287281]
lrwx------ 1 rooslan rooslan 64 2010-09-16 23:56 12 -> pipe:[287281]
lrwx------ 1 rooslan rooslan 64 2010-09-16 23:56 13 -> socket:[287284]
lrwx------ 1 rooslan rooslan 64 2010-09-16 23:56 14 -> /home/rooslan/.mozilla/firefox/xxxxxxxx.default/cert8.db
l-wx------ 1 rooslan rooslan 64 2010-09-16 23:56 15 -> /home/rooslan/.mozilla/firefox/xxxxxxxx.default/key3.db
lrwx------ 1 rooslan rooslan 64 2010-09-16 23:56 16 -> /tmp/FlashXXpOdDuF (deleted)
lrwx------ 1 rooslan rooslan 64 2010-09-16 23:56 17 -> pipe:[396658]
lrwx------ 1 rooslan rooslan 64 2010-09-16 23:56 18 -> pipe:[396658]
lr-x------ 1 rooslan rooslan 64 2010-09-16 23:56 19 -> pipe:[396659]
l-wx------ 1 rooslan rooslan 64 2010-09-16 23:56 2 -> pipe:[9649]
l-wx------ 1 rooslan rooslan 64 2010-09-16 23:56 20 -> pipe:[396659]
lr-x------ 1 rooslan rooslan 64 2010-09-16 23:56 21 -> socket:[396663]
lrwx------ 1 rooslan rooslan 64 2010-09-16 23:56 3 -> socket:[287192]
lr-x------ 1 rooslan rooslan 64 2010-09-16 23:56 4 -> anon_inode:[eventpoll]
l-wx------ 1 rooslan rooslan 64 2010-09-16 23:56 5 -> socket:[287277]
lr-x------ 1 rooslan rooslan 64 2010-09-16 23:56 6 -> socket:[287278]
l-wx------ 1 rooslan rooslan 64 2010-09-16 23:56 7 -> pipe:[287279]
lr-x------ 1 rooslan rooslan 64 2010-09-16 23:56 8 -> pipe:[287279]
l-wx------ 1 rooslan rooslan 64 2010-09-16 23:56 9 -> pipe:[287280]
(Here, by the way, is another way to view files opened by the process, in addition to
lsof
). And, although readlink returns the names of nonexistent files for some of these links, you can safely read from them (if permissions allow), which we will use:
$ cp /proc/10099/fd/16 video.flv
That's all. These are quite trivial things (many, I think, have guessed what will be discussed from the heading alone), but, I hope, for someone this simple trick will be useful.
UPD
kreon designed these actions as a script (I allowed myself to modify it a bit by adding an argument):
#!/bin/sh
PID=`ps x | grep libflashplayer.so | grep -v grep | awk '{print $1}'`
FD=`lsof -p $PID | grep Flash | awk '{print $4}' | sed 's/u^//'`
cp /proc/$PID/fd/$FD "$1"
Using:
$ saveflash.sh coolvideo.flv
UPD 2
In the comments, they repeatedly pointed to the irrationality of this method and in return offered a variety of browser programs and plugins for downloading videos. Of course, for downloading from YouTube it will be more convenient to use them (although you still need to see if they have the ability to get video from the browser cache because of the above). However, all these plugins are sharpened on a specific, albeit a fairly large, list of video hosting sites. This method also allows you to get video almost always if the video is downloaded via HTTP, and RTMP streaming is not used.