diff --git a/lib/ffmpeg/movie.rb b/lib/ffmpeg/movie.rb index ac394f58..af52835f 100644 --- a/lib/ffmpeg/movie.rb +++ b/lib/ffmpeg/movie.rb @@ -8,6 +8,7 @@ class Movie attr_reader :path, :duration, :time, :bitrate, :rotation, :creation_time attr_reader :video_stream, :video_codec, :video_bitrate, :colorspace, :width, :height, :sar, :dar, :frame_rate attr_reader :audio_streams, :audio_stream, :audio_codec, :audio_bitrate, :audio_sample_rate, :audio_channels, :audio_tags + attr_reader :subtitle_streams, :subtitle_stream, :subtitle_codec, :subtitle_language attr_reader :container attr_reader :metadata, :format_tags @@ -53,6 +54,7 @@ def initialize(path) else video_streams = @metadata[:streams].select { |stream| stream.key?(:codec_type) and stream[:codec_type] === 'video' } audio_streams = @metadata[:streams].select { |stream| stream.key?(:codec_type) and stream[:codec_type] === 'audio' } + subtitle_streams = @metadata[:streams].select { |stream| stream.key?(:codec_type) and stream[:codec_type] === 'subtitle' } @container = @metadata[:format][:format_name] @@ -62,15 +64,13 @@ def initialize(path) @format_tags = @metadata[:format][:tags] - @creation_time = if @format_tags and @format_tags.key?(:creation_time) - begin - Time.parse(@format_tags[:creation_time]) - rescue ArgumentError - nil - end - else - nil - end + @creation_time = nil + if @format_tags and @format_tags.key?(:creation_time) + begin + @creation_time = Time.parse(@format_tags[:creation_time]) + rescue ArgumentError + end + end @bitrate = @metadata[:format][:bit_rate].to_i @@ -127,6 +127,22 @@ def initialize(path) @audio_stream = audio_stream[:overview] end + @subtitle_streams = subtitle_streams.map do |stream| + { + :index => stream[:index], + :language => stream[:tags][:language], + :codec_name => stream[:codec_tag_string], + :overview => "#{stream[:codec_tag_string]} (#{stream[:tags][:language]})" + } + end + + subtitle_stream = @subtitle_streams.first + unless subtitle_stream.nil? + @subtitle_language = subtitle_stream[:language] + @subtitle_codec = subtitle_stream[:codec_name] + @subtitle_stream = subtitle_stream[:overview] + end + end unsupported_stream_ids = unsupported_streams(std_error) diff --git a/spec/ffmpeg/movie_spec.rb b/spec/ffmpeg/movie_spec.rb index b228a1f2..555f9074 100644 --- a/spec/ffmpeg/movie_spec.rb +++ b/spec/ffmpeg/movie_spec.rb @@ -214,6 +214,14 @@ module FFMPEG end end + context "given a file with a subtitle stream" do + let(:movie) {Movie.new("#{fixture_path}/movies/awesome movie with subtitles.m4v") } + + it "should be valid" do + expect(movie).to be_valid + end + end + context "given a file named with URL characters" do # let(:movie) { Movie.new("#{fixture_path}/movies/file+with+data&streams=works?.mp4") } @@ -509,6 +517,29 @@ module FFMPEG end end + context "given a file with subtitle streams" do + let(:movie) {Movie.new("#{fixture_path}/movies/awesome movie with subtitles.m4v") } + + it "should identify both subtitle streams" do + expect(movie.subtitle_streams.length).to eq(2) + end + + it "should assign subtitle_codec to the format of the first stream" do + subtitle_codec = movie.subtitle_streams[0][:codec_name] + expect(movie.subtitle_codec).to eq(subtitle_codec) + end + + it "should assign subtitle_language to the language of the first stream" do + subtitle_language = movie.subtitle_streams[0][:language] + expect(movie.subtitle_language).to eq(subtitle_language) + end + + it "should assign subtitle_stream to the properties of the first stream" do + stream_overview = movie.subtitle_streams[0][:overview] + expect(movie.subtitle_stream).to eq stream_overview + end + end + describe "transcode" do let(:movie) { Movie.new("#{fixture_path}/movies/awesome movie.mov")} diff --git a/spec/fixtures/movies/awesome movie with subtitles.m4v b/spec/fixtures/movies/awesome movie with subtitles.m4v new file mode 100644 index 00000000..a31eea76 Binary files /dev/null and b/spec/fixtures/movies/awesome movie with subtitles.m4v differ