SitePoint Sponsor

User Tag List

Results 1 to 4 of 4
  1. #1
    SitePoint Member
    Join Date
    Sep 2012
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    capture loaded source of audio tag with ruby n rails

    I have a problem and was wondering if anyone could help. I need to save the source file (the currently loaded source file) of an audio tag. Sounds simple, but here's the catch the source gives a random sound file on every request.

    The audio tag is created, source set and played with javascript.

    ex:
    Code:
    function createAudio() {
        var audio = document.createElement('audio');
    
        audio.setAttribute('id', 'file_audio')
        audio.setAttribute('controls', 'controls');
        audio.setAttribute('autoplay', 'true');
        audio.setAttribute('hidden', 'true');
        audio.appendChild(createSource());
        return audio;
    }
    
    function createSource() {
        var source = document.createElement('source');
        var d = new Date();
        source.setAttribute('id', 'file_audio_source')
        source.setAttribute('src', 'file.wav?r=' + d.getTime());
        source.setAttribute('type', 'audio/wav');
        return source;
    }
    this.switchAudio = function() {
        var d = new Date();
        $svjq("#file_audio").find('audio').remove();
        $svjq("#file_audio").find('source').remove();
        $svjq("#file_audio").find('embed').remove();
        if (Modernizr.audio.wav) {
            document.getElementById("file_audio").appendChild(createAudio());
        } else {
            $svjq("#file_audio").append('<embed id="file_audio_embed" name="file_audio_embed" src="file.wav?r=' + d.getTime() + '" autostart="true" cache="false" type="audio/wav" hidden="true" loop="false" enablejavascript="true">');
        }
    
    };
    this.playAgain = function() {
        if (Modernizr.audio.wav) {
            document.getElementById('file_audio').play();
        } else {
            document.getElementById('file_audio_embed').play();
        }
    };
    I need be able to save the currently loaded file in the source. If you access the file url in the browser it returns a different file. With automated processes, such using Watir-WebDriver, Capybara (Capybara-Webkit), Mechanize It still returns a random file.

    Code:
    require 'capybara'
    session = Capybara::Session.new(:selenium)
    session.visit('url')
    session.click_link 'play sound' #on every click u get a new sound
    session.click_link 'play again'
    
    #file_audio_source
    e = session.find_by_id('file_audio_source')
    e[:src]
    
    #save the current open page and opens it
    #session.save_and_open_page
    
    #returns different file
    session.visit(e[:src])
    
    #returns different file
    session.execute_script("window.open('"+e[:src]+"')")
    
    require 'Mechanize' 
    agent = Mechanize.new{|agent| agent.ssl_version, agent.verify_mode = 'SSLv3', OpenSSL::SSL::VERIFY_NONE}
    
    filedata = agent.get(e[:src]).content
    aFile = File.new("/Users/me/Documents/test/test111.wav", 'wb')
    #aFile.syswrite(filedata)
    Could the file be embedded into the html or cached? And is there a way to get it and save it locally?

    Other options include recording from the sound device, (or using the mic to record the sound played, this option is not the ideal solution at all)

    Many thanks in advance for any assistance or suggestions shared

    I have been struggling with this for far too long =)
    ajt

  2. #2
    padawan silver trophybronze trophy markbrown4's Avatar
    Join Date
    Jul 2006
    Location
    Victoria, Australia
    Posts
    4,095
    Mentioned
    28 Post(s)
    Tagged
    1 Thread(s)
    Hi ajt,

    Could the file be embedded into the html or cached?
    You can use data URI's to embed a file in the src attribute rather than linking to it.
    http://stackoverflow.com/questions/2...and-audio-tags

  3. #3
    SitePoint Member
    Join Date
    Sep 2012
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Thumbs up solved !!!

    So it finally is solved =)
    Two ways to solve it !

    1. Yes it has something to do with the session
    if you load the js that embedds the audio tag and not play it through the browser with js
    then the file you got by executing the js that embeds is the file that would have been loaded.
    >>>> the file needed <<<<
    Code:
    function createSource() {
        var source = document.createElement('source');
        var d = new Date();
        source.setAttribute('id', 'file_audio_source')
        source.setAttribute('src', 'file.wav?r=' + d.getTime());
        source.setAttribute('type', 'audio/wav');
        return source;
    }
    run the above in
    page.execute_script('here')


    2. It is stored in the cache
    So now you just needed to find the location of the cache folder,
    then load the page and go and get the file in the cache (by getting
    the latest/newest wav file in cache)
    test_getfile.rb
    Code:
    #def loadFile
    	 	
    	 	require 'capybara'
    		session = Capybara::Session.new(:selenium)
    		session.visit('url')
    		sleep(5)
    		session.click_link 'Play sound'	
    		sleep(20)		
    		
    	#end
    
    	def getlatestdir(newdirs)
    		times = Array.new
    		newdirs.each_with_index do |newdir,index|
    			times[index] = File::mtime(newdir)
    		end
    
    		temp = times[0]
    		count = 0
    		times.each_with_index do |time,index|
    			if temp < time
    				temp = time
    				count = index
    			end
    		end
    
    		return newdirs[count] 
    	end
    
    	def getCacheDir
    		#how to get the path
    		#in irb enter
    		#require 'capybara'
    		#session = Capybara::Session.new(:selenium)
    		#session.visit('https://www.google.co.za')
    		#--- then open a new tab and enter about:cache
    		#copy the disk cache device cache directory ( from /var/... to .../T/ )
    		path = '/var/folders/9x/51cvmc215xx6zy9vd_64sxwc0000gn/T/'
    		dirs = Dir.glob(path +'*/')
    		newdirs = Array.new
    		dirs.each_with_index do |dir,index|
    			if(dir.include? 'webdriver-profile')
    				newdirs[newdirs.length] = dir
    			end
    		end
    
    		the_cache_dir = getlatestdir(newdirs) + 'Cache'
    
    		puts the_cache_dir
    		return the_cache_dir
    	end
    
    	def saveFile
    		rifffile = ''
    		count = 0
    		the_cache_dir = getCacheDir
    		files = Dir.glob(the_cache_dir + '/*/*/*')
    		files.each_with_index do |file,index|
    			bytes = open(file, 'rb'){|io|io.read}
    			str = bytes[0].to_s + bytes[1].to_s + bytes[2].to_s + bytes[3].to_s
    			#rifffiles[rifffiles.length] = file
                            #finds the wav file by file signature
    			if(str == 'RIFF')
    				count = index
    				rifffile = file
    			end
    			#puts str
    			#puts file
    			#puts File.size(file)		
    		end
    
    		puts rifffile
    
    		#read file bytes
    		bytes = File.open(rifffile, 'rb'){|io|io.read}
    		#write file to your directory
    		f = File.new('testing2.wav', 'wb')
    		f.syswrite(bytes)
    	end
    
    	saveFile
    a big thank you for everyones assistance in solving this issue
    =)
    ajt

  4. #4
    SitePoint Member
    Join Date
    Sep 2012
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by markbrown4 View Post
    Hi ajt,


    You can use data URI's to embed a file in the src attribute rather than linking to it.
    http://stackoverflow.com/questions/2...and-audio-tags
    Thank you, awesome answer.
    Good to know this for the future =)
    The solution was a little easier than first thought.
    I have post the solution.


Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •