1
0
mirror of https://github.com/mpv-player/mpv synced 2025-03-07 14:47:53 +00:00

Add a simple capture feature (-capture)

If a specified key is pressed during playback, the current stream is
captured to a file, similar to what -dumpstream achieves.

original patch by Pásztor Szilárd, don tricon hu

Taken from the following svn commits, but with several fixes and
modifications (one obvious user-visible difference is that the default
key binding is 'C', not 'c'):

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32524 b3059339-0415-0410-9bf9-f77b7e298cf2

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32529 b3059339-0415-0410-9bf9-f77b7e298cf2

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32530 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
Uoti Urpala 2010-11-02 03:17:41 +02:00
parent 2be10f22b2
commit 3cb3bbbddc
10 changed files with 88 additions and 1 deletions

View File

@ -273,6 +273,8 @@ Toggle displaying "forced subtitles".
Toggle subtitle alignment: top / middle / bottom.
.IPs "x and z"
Adjust subtitle delay by +/\- 0.1 seconds.
.IPs "C (\-capture only)"
Start/stop capturing the primary stream.
.IPs "r and t"
Move subtitles up/down.
.IPs "i (\-edlout mode only)"
@ -1248,6 +1250,18 @@ from the current position, MPlayer will wait for the cache to be filled to
this position rather than performing a stream seek (default: 50).
.
.TP
.B \-capture (MPlayer only)
Allows capturing the primary stream (not additional audio tracks or other
kind of streams) into the file specified by \-dumpfile or \"stream.dump\"
by default.
If this option is given, capturing can be started and stopped by pressing
the key bound to this function (see section INTERACTIVE CONTROL).
Same as for \-dumpstream, this will likely not produce usable results for
anything else than MPEG streams.
Note that, due to cache latencies, captured data may begin and end
somewhat delayed compared to what you see displayed.
.
.TP
.B \-cdda <option1:option2> (CDDA only)
This option can be used to tune the CD Audio reading feature of MPlayer.
.sp 1
@ -1379,7 +1393,8 @@ on the command line only the last one will work.
.TP
.B \-dumpfile <filename> (MPlayer only)
Specify which file MPlayer should dump to.
Should be used together with \-dumpaudio / \-dumpvideo / \-dumpstream.
Should be used together with \-dumpaudio / \-dumpvideo / \-dumpstream /
\-capture.
.
.TP
.B \-dumpstream (MPlayer only)

View File

@ -76,6 +76,10 @@ audio_delay <value> [abs]
If [abs] is non-zero, parameter is set to <value>.
<value> is in the range [-100, 100].
capturing [value]
Toggle/set capturing the primary stream like -dumpstream.
Requires the -capture parameter to be given.
change_rectangle <val1> <val2>
Change the position of the rectangle filter rectangle.
<val1>
@ -538,6 +542,7 @@ channels int X
switch_audio int -2 255 X X X select audio stream
switch_angle int -2 255 X X X select DVD angle
switch_title int -2 255 X X X select DVD title
capturing flag 0 1 X X X dump primary stream if enabled
fullscreen flag 0 1 X X X
deinterlace flag 0 1 X X X
ontop flag 0 1 X X X

View File

@ -294,6 +294,9 @@ const m_option_t mplayer_opts[]={
{"dumpjacosub", &stream_dump_type, CONF_TYPE_FLAG, 0, 0, 8, NULL},
{"dumpsami", &stream_dump_type, CONF_TYPE_FLAG, 0, 0, 9, NULL},
OPT_FLAG_ON("capture", capture_dump, 0),
OPT_FLAG_OFF("nocapture", capture_dump, 0),
#ifdef CONFIG_LIRC
{"lircconf", &lirc_configfile, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL},
#endif

View File

@ -1178,6 +1178,40 @@ static int mp_property_yuv_colorspace(m_option_t *prop, int action,
return M_PROPERTY_NOT_IMPLEMENTED;
}
static int mp_property_capture(m_option_t *prop, int action,
void *arg, MPContext *mpctx)
{
struct MPOpts *opts = &mpctx->opts;
if (!mpctx->stream)
return M_PROPERTY_UNAVAILABLE;
if (!opts->capture_dump) {
mp_tmsg(MSGT_GLOBAL, MSGL_ERR,
"Capturing not enabled (forgot -capture parameter?)\n");
return M_PROPERTY_ERROR;
}
int capturing = !!mpctx->stream->capture_file;
int ret = m_property_flag(prop, action, arg, &capturing);
if (ret == M_PROPERTY_OK && capturing != !!mpctx->stream->capture_file) {
if (capturing) {
mpctx->stream->capture_file = fopen(opts->stream_dump_name, "wb");
if (!mpctx->stream->capture_file) {
mp_tmsg(MSGT_GLOBAL, MSGL_ERR,
"Error opening capture file: %s\n", strerror(errno));
ret = M_PROPERTY_ERROR;
}
} else {
fclose(mpctx->stream->capture_file);
mpctx->stream->capture_file = NULL;
}
}
return ret;
}
/// Panscan (RW)
static int mp_property_panscan(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
@ -2158,6 +2192,8 @@ static const m_option_t mp_properties[] = {
0, 0, 0, NULL },
{ "pause", mp_property_pause, CONF_TYPE_FLAG,
M_OPT_RANGE, 0, 1, NULL },
{ "capturing", mp_property_capture, CONF_TYPE_FLAG,
M_OPT_RANGE, 0, 1, NULL },
// Audio
{ "volume", mp_property_volume, CONF_TYPE_FLOAT,
@ -2330,6 +2366,7 @@ static struct property_osd_display {
// general
{ "loop", 0, -1, _("Loop: %s") },
{ "chapter", -1, -1, NULL },
{ "capturing", 0, -1, _("Capturing: %s") },
// audio
{ "volume", OSD_VOLUME, -1, _("Volume") },
{ "mute", 0, -1, _("Mute: %s") },
@ -2456,6 +2493,7 @@ static struct {
{ "chapter", MP_CMD_SEEK_CHAPTER, 0},
{ "angle", MP_CMD_SWITCH_ANGLE, 0},
{ "pause", MP_CMD_PAUSE, 0},
{ "capturing", MP_CMD_CAPTURING, 1},
// audio
{ "volume", MP_CMD_VOLUME, 0},
{ "mute", MP_CMD_MUTE, 1},

View File

@ -183,6 +183,7 @@ static const mp_cmd_t mp_cmds[] = {
{ MP_CMD_LOADFILE, "loadfile", 1, { {MP_CMD_ARG_STRING, {0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
{ MP_CMD_LOADLIST, "loadlist", 1, { {MP_CMD_ARG_STRING, {0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
{ MP_CMD_RUN, "run", 1, { {MP_CMD_ARG_STRING,{0}}, {-1,{0}} } },
{ MP_CMD_CAPTURING, "capturing", 0, { {-1,{0}} } },
{ MP_CMD_VF_CHANGE_RECTANGLE, "change_rectangle", 2, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}}}},
{ MP_CMD_TV_TELETEXT_ADD_DEC, "teletext_add_dec", 1, { {MP_CMD_ARG_STRING,{0}}, {-1,{0}} } },
{ MP_CMD_TV_TELETEXT_GO_LINK, "teletext_go_link", 1, { {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
@ -475,6 +476,7 @@ static const mp_cmd_bind_t def_cmd_binds[] = {
#endif
{ { 'T', 0 }, "vo_ontop" },
{ { 'f', 0 }, "vo_fullscreen" },
{ { 'C', 0 }, "step_property_osd capturing" },
{ { 's', 0 }, "screenshot 0" },
{ { 'S', 0 }, "screenshot 1" },
{ { 'w', 0 }, "panscan -0.1" },

View File

@ -41,6 +41,7 @@ typedef enum {
MP_CMD_TV_STEP_CHANNEL,
MP_CMD_TV_STEP_NORM,
MP_CMD_TV_STEP_CHANNEL_LIST,
MP_CMD_CAPTURING,
MP_CMD_VO_FULLSCREEN,
MP_CMD_SUB_POS,
MP_CMD_DVDNAV,

View File

@ -28,6 +28,7 @@ typedef struct MPOpts {
int osd_level;
int osd_duration;
char *stream_dump_name;
int capture_dump;
int loop_times;
int ordered_chapters;
int chapterrange[2];

View File

@ -508,6 +508,8 @@ int cache_stream_fill_buffer(stream_t *s){
s->buf_len=len;
s->pos+=len;
// printf("[%d]",len);fflush(stdout);
if (s->capture_file)
stream_capture_do(s);
return len;
}

View File

@ -265,6 +265,16 @@ stream_t *open_output_stream(const char *filename, struct MPOpts *options)
//=================== STREAMER =========================
void stream_capture_do(stream_t *s)
{
if (fwrite(s->buffer, s->buf_len, 1, s->capture_file) < 1) {
mp_tmsg(MSGT_GLOBAL, MSGL_ERR, "Error writing capture file: %s\n",
strerror(errno));
fclose(s->capture_file);
s->capture_file = NULL;
}
}
int stream_fill_buffer(stream_t *s){
int len;
// we will retry even if we already reached EOF previously.
@ -296,6 +306,8 @@ int stream_fill_buffer(stream_t *s){
s->buf_len=len;
s->pos+=len;
// printf("[%d]",len);fflush(stdout);
if (s->capture_file)
stream_capture_do(s);
return len;
}
@ -463,6 +475,11 @@ void free_stream(stream_t *s){
#ifdef CONFIG_STREAM_CACHE
cache_uninit(s);
#endif
if (s->capture_file) {
fclose(s->capture_file);
s->capture_file = NULL;
}
if(s->close) s->close(s);
if(s->fd>0){
/* on unix we define closesocket to close

View File

@ -22,6 +22,7 @@
#include "config.h"
#include "mp_msg.h"
#include "url.h"
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <sys/types.h>
@ -168,6 +169,7 @@ typedef struct stream {
streaming_ctrl_t *streaming_ctrl;
#endif
unsigned char buffer[STREAM_BUFFER_SIZE>STREAM_MAX_SECTOR_SIZE?STREAM_BUFFER_SIZE:STREAM_MAX_SECTOR_SIZE];
FILE *capture_file;
} stream_t;
#ifdef CONFIG_NETWORKING
@ -176,6 +178,7 @@ typedef struct stream {
int stream_fill_buffer(stream_t *s);
int stream_seek_long(stream_t *s, off_t pos);
void stream_capture_do(stream_t *s);
#ifdef CONFIG_STREAM_CACHE
int stream_enable_cache(stream_t *stream,int size,int min,int prefill);