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()