Help with recording with transcode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



Not sure if this is the correct place to ask...if not kindly point me in
the correct direction....

I am trying to record TV from my capture card.  The video is working
just fine but I'm not getting any audio during recording.  The xawtv
application is playing TV just fine with audio.

I am using the attached "recordtv-noch" script.  When the call is made
to v4lctl setchannel I can hear audio out my speakers.  After the 3
second sleep when transcode is called the audio is gone.

I was "lucky" once where the audio stayed on my speakers and the end
result was recorded video and audio.

Do you have any suggestions?

-- 
"An opinion is like an asshole - everybody has one."
    - Clint Eastwood as Harry Callahan, The Dead Pool - 1988.
#!/usr/bin/env python
#
# Written by Ben Escoto <bescoto@xxxxxxxxxxxx>
# Feel free to modify and/or distribute this.

import os, sys, re, time, getopt

# The four commands below should be changed to fit the individual
# system.

# The first %s will be replaced by the number of frames to record,
# the second two to the file prefix.
recording_cmd_schema = "transcode -V -H0 -k -p /dev/dsp -i /dev/video0 -x nvrec='-norm NTSC -input Television -F %s -wav',null -y yuv4mpeg,null -o %s_video.yuv4mpeg -g 352x240 -u 100 -m %s_audio.avi -f 30 -e 44100,16,2"

# The two %s's will be replaced by the file prefix
denoising_cmd_schema = "nice transcode -V -i %s_video.yuv4mpeg -g 352x240 -f 30 -x yuv4mpeg,null -y yuv4mpeg,null -o %s_denoised.yuv4mpeg -u 100 -J yuvdenoise=deinterlace=0,dnr -q0"

# All three %s's will be replaced by the file prefix
encoding1_cmd_schema = "nice transcode -k -V -i %s_denoised.yuv4mpeg -p %s_audio.avi -g 352x240 -f 30 -x yuv4mpeg,raw -y xvid -w 3000 -o %s.avi -u 100 -e 44100,16,2 --divx_quant 2,10 -R 1 -q0"

# All three %s's will be replaced by the file prefix.
encoding2_cmd_schema = "nice transcode -k -V -i %s_denoised.yuv4mpeg -p %s_audio.avi -g 352x240 -f 30 -x yuv4mpeg,raw -y xvid -w 3000 -o %s.avi -u 100 -e 44100,16,2 --divx_quant 2,10 -R 2 -q0"

# This should be the same framerate as in the schema above
framerate = 30

# The directory that all the files go in
directory = "/home/egreshko/tv"

# video volume length -- maximum length of a video.  If asked to
# record for a time longer than this, split into multiple videos.
vol_length = 300

####### The following are set by the program, not in advance by the user ####

# Set to the file prefix as a string
file_prefix = None

# Length of time to record in seconds.
record_length = None

# Channel as a integer
channel = None

# time string when to start recording -- passed to 'at'
record_time = None

# If true, do not tape, just process queue
only_process_queue = None

# If true, do not process the queue, just record
do_not_process_queue = None


def print_syntax():
	"""Print the instructions and exit"""
	print ("Syntax: %s [args] file_prefix channel duration [time]"
		   % (sys.argv[0],))
	print
	print "Records video from channel for duration with file_prefix."
	print "If a [time] is given then 'at' will be run and recordtv will"
	print "be scheduled to run at that time."
	print
	print "Two options are recognized: -q only process the queue, and does"
	print "not record.  -n means not to process the queue after recording."
	sys.exit(1)

def process_args():
	"""Process the command line arguments"""
	global file_prefix, record_length, channel, record_time
	global only_process_queue, do_not_process_queue
	opt_pairs, args = getopt.getopt(sys.argv[1:], "qn")

	for opt, optarg in opt_pairs:
		if opt == "-q":
			only_process_queue = 1
			return
		elif opt == "-n": do_not_process_queue = 1
		else: assert 0, "Bad option %s" % (opt,)

	if not (3 <= len(args) <= 4):
		sys.stderr.write("Wrong number of command line arguments\n")
		print_syntax()

	file_prefix = args[0]
	try: channel = int(args[1])
	except ValueError:
		sys.stderr.write("Bad channel %s\n" % (args[1],))
		print_syntax()

	record_length = get_time_in_seconds(args[2])
	if not record_length:
		sys.stderr.write("Bad time string %s\n" % (args[2],))
		print_syntax()

	if len(args) == 4: record_time = args[3]

def get_time_in_seconds(timestr):
	"""Return time in seconds from string like '30:00', or None"""
	if re.search("^[0-9]{1,2}$", timestr): return int(timestr)

	m2 = re.search("^([0-9]{1,2}):([0-9]{2})$", timestr)
	if m2: return int(m2.group(1))*60 + int(m2.group(2))

	m3 = re.search("^([0-9]):([0-9]{1,2}):([0-9]{2})$", timestr)
	if m3: return (int(m3.group(1))*3600 + int(m3.group(2))*60
				   + int(m3.group(3)))
	return None

def process_queue():
	"""Processes the queue, returns None if there is nothing to do

	This just lists the directory, telling which files need what to
	them just be what exists in the directory.  Files are denoised and
	encoded as appropriate.  There is the possibility of a race
	condition, but seems unlikely.

	"""
	pair = parse_queue()
	if pair is None:
		print "Warning: Queue appears to be in process"
		return None
	else:
		recorded, denoised = pair
		if denoised: run_compress(denoised[0])
		elif recorded: run_denoise(recorded[0])
		else: return None
	return 1

def parse_queue():
	"""Read the directory, and return (recorded, denoised) file prefixes

	Just return a file prefix if it is in the queue and does not
	appear to be already being processed (i.e. files corresponding to
	the next step in the pipeline are not present).

	Also returns None if it seems something else is being processed at
	the moment.

	"""
	global directory
	recorded_prefix_dict = {}
	denoised_prefix_dict = {}
	finished_prefix_dict = {}
	for filename in os.listdir(directory):
		if filename.endswith("_video.yuv4mpeg"):
			recorded_prefix_dict[filename[:-len("_video.yuv4mpeg")]] = 1
		elif filename.endswith("_denoised.yuv4mpeg"):
			denoised_prefix_dict[filename[:-len("_denoised.yuv4mpeg")]] = 1
		elif (filename.endswith(".avi") and
			  not filename.endswith("_audio.avi")):
			finished_prefix_dict[filename[:-len(".avi")]] = 1

	recorded_prefixes = []
	for prefix in recorded_prefix_dict.keys():
		if not denoised_prefix_dict.has_key(prefix):
			recorded_prefixes.append(prefix)
		else: return None

	denoised_prefixes = []
	for prefix in denoised_prefix_dict.keys():
		if not finished_prefix_dict.has_key(prefix):
			denoised_prefixes.append(prefix)
		else: return None
			
	print "Debug recorded_prefixes: ", recorded_prefixes
	print "Debug denoised_prefixes: ", denoised_prefixes
	return recorded_prefixes, denoised_prefixes

def run(cmd):
	"""Runs the given command with logging and error checking"""
	print "About to run: ", cmd
	assert not os.system(cmd)

def run_compress(prefix):
	"""Compress the denoised files with the given prefix, create prefix.avi"""
	run(encoding1_cmd_schema % (prefix, prefix, prefix))
	run(encoding2_cmd_schema % (prefix, prefix, prefix))
	os.remove(os.path.join(directory, "%s_denoised.yuv4mpeg" % (prefix,)))
	os.remove(os.path.join(directory, "%s_audio.avi" % (prefix,)))
	run("sync") # sync to confirm deletes

def run_denoise(prefix):
	"""Denoise the raw video files with the given prefix"""
	run(denoising_cmd_schema % (prefix, prefix))
	os.remove(os.path.join(directory, "%s_video.yuv4mpeg" % (prefix,)))
	run("sync") # sync to confirm deletes

def record():
	"""Write the raw video from disk as given in global variables

	Split into multiple volumes as given by the vol_length variable.
	We do this so audio and video don't get too out of sync for too
	long.

	"""
	global record_length, file_prefix, vol_length

	start_time = time.time()
	cur_vol_num = 1
	while time.time() + vol_length <= start_time + record_length:
		record_for_length(vol_length, "%s-%02d" % (file_prefix, cur_vol_num))
		cur_vol_num += 1
	remainder = int(start_time + record_length - time.time())
	if remainder > 0:
		record_for_length(remainder, "%s-%02d" % (file_prefix, cur_vol_num))

def record_for_length(time_length, prefix):
	"""Record for the given time length"""
	global channel, framerate
	run("v4lctl setchannel %s" % (channel,))
	run("sleep 3")
	frames = framerate * time_length
	run(recording_cmd_schema % (frames, prefix, prefix))

def load_job():
	"""Give recordtv job to at for later running"""
	global record_time
	recordtv_cmd = " ".join(sys.argv[:-1])
	print "Job is '%s' at '%s'" % (recordtv_cmd, record_time)
	run("echo %s | at %s" % (recordtv_cmd, record_time))

def Main():
	"""Start and end here"""
	os.chdir(directory)
	process_args()
	if only_process_queue:
		while process_queue(): pass
	elif record_time: load_job()
	else:
		record()
		if not do_not_process_queue:
			while process_queue(): pass

if __name__=="__main__": Main()

[Index of Archives]     [Linux DVB]     [Video Disk Recorder]     [Asterisk]     [Photo]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Free Photo Albums]     [Fedora Users]     [Fedora Women]     [ALSA Users]     [ALSA Devel]     [Linux USB]

Powered by Linux