2017-02-05 2 views
0

私の反応アプリケーションではvideojsを使用しています。私はそれにrangesliderを加えました。私のビデオプレーヤーの近くにボタンがあり、これは、ビデオプレーヤーに表示するために、範囲のスライダーをトリガーします。すべてのことはうまくいきますが、範囲の始まりの矢印はボタンをクリックした時点ではありません。開始ボタンは常に時刻0:0にあります。私が欲しいのは、ビデオが現時点で30時に再生されていて、ショーボタンをクリックしたとしたら、rangesliderは30秒だけで始まり、0秒ではないことを示すはずです。私はvideojsプレーヤーの現在の時間を取得し、それをrangeslider.jsプラグインに渡すことができますが、どこに渡すべきか分かりません。範囲の開始点を変更するvideojs

これは私のrangeslider.js(私はそれは長いコードを知っているが、私は結果を達成するために使用することのどの部分かわからない)

//----------------Load Plugin----------------// 
(function() { 
    var videojsAddClass = function (element, className) { 
     element.classList.add(className); 
    }; 
    var videojsRemoveClass = function (element, className) { 
     element.classList.remove(className); 
    }; 
    var videojsFindPosition = function (element) { 
     return element.getBoundingClientRect(); 
    }; 

    var videojsRound = function (n, precision) { 
     return parseFloat(n.toFixed(precision)); 
    }; 
    var videojsFormatTime = function (totalSeconds) { 
     var minutes = Math.floor(totalSeconds/60).toFixed(0); 
     var seconds = (totalSeconds % 60).toFixed(0); 

     if (seconds.length === 1) { 
      seconds = "0" + seconds; 
     } 

     return minutes + ':' + seconds; 
    }; 
    var videojsBlockTextSelection = function() { 
     // TODO 
    }; 

//-- Load RangeSlider plugin in videojs 
    function RangeSlider_(options) { 
     var player = this; 

     player.rangeslider = new RangeSlider(player, options); 

     //When the DOM and the video media is loaded 
     function initialVideoFinished(event) { 
      var plugin = player.rangeslider; 
      //All components will be initialize after they have been loaded by videojs 
      for (var index in plugin.components) { 
       plugin.components[index].init_(); 
      } 

      if (plugin.options.hidden) 
       plugin.hide(); //Hide the Range Slider 

      if (plugin.options.locked) 
       plugin.lock(); //Lock the Range Slider 

      if (plugin.options.panel == false) 
       plugin.hidePanel(); //Hide the second Panel 

      if (plugin.options.controlTime == false) 
       plugin.hidecontrolTime(); //Hide the control time panel 

      plugin._reset(); 
      player.trigger('loadedRangeSlider'); //Let know if the Range Slider DOM is ready 
     } 
     if (player.techName == 'Youtube') { 
      //Detect youtube problems 
      player.one('error', function (e) { 
       switch (player.error) { 
        case 2: 
         alert("The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks."); 
        case 5: 
         alert("The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred."); 
        case 100: 
         alert("The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private."); 
         break; 
        case 101: 
         alert("The owner of the requested video does not allow it to be played in embedded players."); 
         break; 
        case 150: 
         alert("The owner of the requested video does not allow it to be played in embedded players."); 
         break; 
        default: 
         alert("Unknown Error"); 
         break; 
       } 
      }); 
      player.on('firstplay', initialVideoFinished); 
     } else { 
      player.one('playing', initialVideoFinished); 
     } 

    } 
    videojs.plugin('rangeslider', RangeSlider_); 



//-- Plugin 
    function RangeSlider(player, options) { 
     var player = player || this; 

     this.player = player; 

     this.components = {}; // holds any custom components we add to the player 

     options = options || {}; // plugin options 

     if (!options.hasOwnProperty('locked')) 
      options.locked = false; // lock slider handles 

     if (!options.hasOwnProperty('hidden')) 
      options.hidden = true; // hide slider handles 

     if (!options.hasOwnProperty('panel')) 
      options.panel = true; // Show Second Panel 

     if (!options.hasOwnProperty('controlTime')) 
      options.controlTime = true; // Show Control Time to set the arrows in the edition 

     this.options = options; 

     this.init(); 
    } 

//-- Methods 
    RangeSlider.prototype = { 
     /*Constructor*/ 
     init: function() { 
      var player = this.player || {}; 

      this.updatePrecision = 3; 

      //position in second of the arrows 
      this.start = 0; 
      this.end = 0; 

      //components of the plugin 
      var controlBar = player.controlBar; 
      var seekBar = controlBar.progressControl.seekBar; 
      this.components.RSTimeBar = seekBar.RSTimeBar; 
      this.components.ControlTimePanel = controlBar.ControlTimePanel; 

      //Save local component 
      this.rstb = this.components.RSTimeBar; 
      this.box = this.components.SeekRSBar = this.rstb.SeekRSBar; 
      this.bar = this.components.SelectionBar = this.box.SelectionBar; 
      this.left = this.components.SelectionBarLeft = this.box.SelectionBarLeft; 
      this.right = this.components.SelectionBarRight = this.box.SelectionBarRight; 
      this.tp = this.components.TimePanel = this.box.TimePanel; 
      this.tpl = this.components.TimePanelLeft = this.tp.TimePanelLeft; 
      this.tpr = this.components.TimePanelRight = this.tp.TimePanelRight; 
      this.ctp = this.components.ControlTimePanel; 
      this.ctpl = this.components.ControlTimePanelLeft = this.ctp.ControlTimePanelLeft; 
      this.ctpr = this.components.ControlTimePanelRight = this.ctp.ControlTimePanelRight; 

     }, 

     show: function() { 
      this.options.hidden = false; 
      if (typeof this.rstb != 'undefined') { 
       this.rstb.show(); 
       if (this.options.controlTime) 
        this.showcontrolTime(); 
      } 
     }, 
     hide: function() { 
      this.options.hidden = true; 
      if (typeof this.rstb != 'undefined') { 
       this.rstb.hide(); 
       this.ctp.hide(); 
      } 
     }, 
     showPanel: function() { 
      this.options.panel = true; 
      if (typeof this.tp != 'undefined') 
       videojsRemoveClass(this.tp.el_, 'disable'); 
     }, 

     showcontrolTime: function() { 
      this.options.controlTime = true; 
      if (typeof this.ctp != 'undefined') 
       this.ctp.show(); 
     }, 
     hidecontrolTime: function() { 
      this.options.controlTime = false; 
      if (typeof this.ctp != 'undefined') 
       this.ctp.hide(); 
     }, 
     setValue: function (index, seconds, writeControlTime) { 
      //index = 0 for the left Arrow and 1 for the right Arrow. Value in seconds 
      var writeControlTime = typeof writeControlTime != 'undefined' ? writeControlTime : true; 

      var percent = this._percent(seconds); 
      var isValidIndex = (index === 0 || index === 1); 
      var isChangeable = !this.locked; 
      if (isChangeable && isValidIndex) 
       this.box.setPosition(index, percent, writeControlTime); 
     }, 
     setValues: function (start, end, writeControlTime) { 
      //index = 0 for the left Arrow and 1 for the right Arrow. Value in seconds 
      var writeControlTime = typeof writeControlTime != 'undefined' ? writeControlTime : true; 

      this._reset(); 

      this._setValuesLocked(start, end, writeControlTime); 
     }, 
     getValues: function() { //get values in seconds 
      var values = {}, start, end; 
      start = this.start || this._getArrowValue(0); 
      end = this.end || this._getArrowValue(1); 
      return {start: start, end: end}; 
     }, 


     _getArrowValue: function (index) { 
      var index = index || 0; 
      var duration = this.player.duration(); 

      duration = typeof duration == 'undefined' ? 0 : duration; 

      var percentage = this[index === 0 ? "left" : "right"].el_.style.left.replace("%", ""); 
      if (percentage == "") 
       percentage = index === 0 ? 0 : 100; 

      return videojsRound(this._seconds(percentage/100), this.updatePrecision - 1); 
     }, 
     _percent: function (seconds) { 
      var duration = this.player.duration(); 
      if (isNaN(duration)) { 
       return 0; 
      } 
      return Math.min(1, Math.max(0, seconds/duration)); 
     }, 
     _seconds: function (percent) { 
      var duration = this.player.duration(); 
      if (isNaN(duration)) { 
       return 0; 
      } 
      return Math.min(duration, Math.max(0, percent * duration)); 
     }, 
     _reset: function() { 
      var duration = this.player.duration(); 
      this.tpl.el_.style.left = '0%'; 
      this.tpr.el_.style.left = '100%'; 
      this._setValuesLocked(0, duration); 
     }, 
     _setValuesLocked: function (start, end, writeControlTime) { 
      var triggerSliderChange = typeof writeControlTime != 'undefined'; 
      var writeControlTime = typeof writeControlTime != 'undefined' ? writeControlTime : true; 
      if (this.options.locked) { 
       this.unlock();//It is unlocked to change the bar position. In the end it will return the value. 
       this.setValue(0, start, writeControlTime); 
       this.setValue(1, end, writeControlTime); 
       this.lock(); 
      } else { 
       this.setValue(0, start, writeControlTime); 
       this.setValue(1, end, writeControlTime); 
      } 

      // Trigger slider change 
      if (triggerSliderChange) { 
       this._triggerSliderChange(); 
      } 
     }, 
     _checkControlTime: function (index, TextInput, timeOld) { 
      var h = TextInput[0], 
       m = TextInput[1], 
       s = TextInput[2], 
       newHour = h.value, 
       newMin = m.value, 
       newSec = s.value, 
       obj, objNew, objOld; 
      index = index || 0; 

      if (newHour != timeOld[0]) { 
       obj = h; 
       objNew = newHour; 
       objOld = timeOld[0]; 
      } else if (newMin != timeOld[1]) { 
       obj = m; 
       objNew = newMin; 
       objOld = timeOld[1]; 
      } else if (newSec != timeOld[2]) { 
       obj = s; 
       objNew = newSec; 
       objOld = timeOld[2]; 
      } else { 
       return false; 
      } 

      var duration = this.player.duration() || 0, 
       durationSel; 

      var intRegex = /^\d+$/;//check if the objNew is an integer 
      if (!intRegex.test(objNew) || objNew > 60) { 
       objNew = objNew == "" ? "" : objOld; 
      } 

      newHour = newHour == "" ? 0 : newHour; 
      newMin = newMin == "" ? 0 : newMin; 
      newSec = newSec == "" ? 0 : newSec; 

      durationSel = videojs.TextTrack.prototype.parseCueTime(newHour + ":" + newMin + ":" + newSec); 
      if (durationSel > duration) { 
       obj.value = objOld; 
       obj.style.border = "1px solid red"; 
      } else { 
       obj.value = objNew; 
       h.style.border = m.style.border = s.style.border = "1px solid transparent"; 
       this.setValue(index, durationSel, false); 

       // Trigger slider change 
       this._triggerSliderChange(); 
      } 
      if (index === 1) { 
       var oldTimeLeft = this.ctpl.el_.children, 
        durationSelLeft = videojs.TextTrack.prototype.parseCueTime(oldTimeLeft[0].value + ":" + oldTimeLeft[1].value + ":" + oldTimeLeft[2].value); 
       if (durationSel < durationSelLeft) { 
        obj.style.border = "1px solid red"; 
       } 
      } else { 

       var oldTimeRight = this.ctpr.el_.children, 
        durationSelRight = videojs.TextTrack.prototype.parseCueTime(oldTimeRight[0].value + ":" + oldTimeRight[1].value + ":" + oldTimeRight[2].value); 
       if (durationSel > durationSelRight) { 
        obj.style.border = "1px solid red"; 
       } 
      } 
     }, 
     _triggerSliderChange: function() { 
      this.player.trigger("sliderchange"); 
     } 
    }; 


//----------------Public Functions----------------// 

//-- Public Functions added to video-js 

    var videojsPlayer = videojs.getComponent('Player'); 

//Lock the Slider bar and it will not be possible to change the arrow positions 
    videojsPlayer.prototype.lockSlider = function() { 
     return this.rangeslider.lock(); 
    }; 

//Unlock the Slider bar and it will be possible to change the arrow positions 
    videojsPlayer.prototype.unlockSlider = function() { 
     return this.rangeslider.unlock(); 
    }; 

//Show the Slider Bar Component 
    videojsPlayer.prototype.showSlider = function() { 
     return this.rangeslider.show(); 
    }; 

//Hide the Slider Bar Component 
    videojsPlayer.prototype.hideSlider = function() { 
     return this.rangeslider.hide(); 
    }; 

//Show the Panel with the seconds of the selection 
    videojsPlayer.prototype.showSliderPanel = function() { 
     return this.rangeslider.showPanel(); 
    }; 

//Hide the Panel with the seconds of the selection 
    videojsPlayer.prototype.hideSliderPanel = function() { 
     return this.rangeslider.hidePanel(); 
    }; 


//Show the control Time to edit the position of the arrows 
    videojsPlayer.prototype.showControlTime = function() { 
     return this.rangeslider.showcontrolTime(); 
    }; 

//Hide the control Time to edit the position of the arrows 
    videojsPlayer.prototype.hideControlTime = function() { 
     return this.rangeslider.hidecontrolTime(); 
    }; 

//Set a Value in second for both arrows 
    videojsPlayer.prototype.setValueSlider = function (start, end) { 
     return this.rangeslider.setValues(start, end); 
    }; 

//The video will be played in a selected section 
    videojsPlayer.prototype.playBetween = function (start, end) { 
     return this.rangeslider.playBetween(start, end); 
    }; 

//The video will loop between to values 
    videojsPlayer.prototype.loopBetween = function (start, end) { 
     return this.rangeslider.loop(start, end); 
    }; 

//Set a Value in second for the arrows 
    videojsPlayer.prototype.getValueSlider = function() { 
     return this.rangeslider.getValues(); 
    }; 



//----------------Create new Components----------------// 

//--Charge the new Component into videojs 
    var videojsSeekBar = videojs.getComponent('SeekBar'); 
    videojsSeekBar.prototype.options_.children.push('RSTimeBar'); //Range Slider Time Bar 

    var videojsControlBar = videojs.getComponent('ControlBar'); 
    videojsControlBar.prototype.options_.children.push('ControlTimePanel'); //Panel with the time of the range slider 



//-- Design the new components 

    var videojsComponent = videojs.getComponent('Component'); 

    /** 
    * Range Slider Time Bar 
    * @param {videojs.Player|Object} player 
    * @param {Object=} options 
    * @constructor 
    */ 
    var videojsRSTimeBar = videojs.extend(videojsComponent, { 
     /** @constructor */ 
     constructor: function (player, options) { 
      videojsComponent.call(this, player, options); 
     } 
    }); 

    videojsRSTimeBar.prototype.init_ = function() { 
     this.rs = this.player_.rangeslider; 
    }; 

    videojsRSTimeBar.prototype.options_ = { 
     children: { 
      'SeekRSBar': {} 
     } 
    }; 

    videojsRSTimeBar.prototype.createEl = function() { 
     return videojsComponent.prototype.createEl.call(this, 'div', { 
      className: 'vjs-timebar-RS', 
      innerHTML: '' 
     }); 
    }; 

    videojs.registerComponent('RSTimeBar', videojsRSTimeBar); 

    /** 
    * Seek Range Slider Bar and holder for the selection bars 
    * @param {videojs.Player|Object} player 
    * @param {Object=} options 
    * @constructor 
    */ 
    var videojsSeekRSBar = videojs.extend(videojsSeekBar, { 
     /** @constructor */ 
     constructor: function (player, options) { 
      videojsComponent.call(this, player, options); 
      this.on('mousedown', this.onMouseDown); 
      this.on('touchstart', this.onMouseDown); 
     } 
    }); 

    videojsSeekRSBar.prototype.init_ = function() { 
     this.rs = this.player_.rangeslider; 
    }; 

    videojsSeekRSBar.prototype.options_ = { 
     children: { 
      'SelectionBar': {}, 
      'SelectionBarLeft': {}, 
      'SelectionBarRight': {}, 
      'TimePanel': {}, 
     } 
    }; 

    videojsSeekRSBar.prototype.createEl = function() { 
     return videojsComponent.prototype.createEl.call(this, 'div', { 
      className: 'vjs-rangeslider-holder' 
     }); 
    }; 


    videojsSeekRSBar.prototype.onMouseDown = function (event) { 
     event.preventDefault(); 
     videojsBlockTextSelection(); 

     if (!this.rs.options.locked) { 
      this.on(document, "mousemove", videojs.bind(this, this.onMouseMove)); 
      this.on(document, "mouseup", videojs.bind(this, this.onMouseUp)); 
      this.on(document, "touchmove", videojs.bind(this, this.onMouseMove)); 
      this.on(document, "touchend", videojs.bind(this, this.onMouseUp)); 

     } 
    }; 

    videojsSeekRSBar.prototype.onMouseUp = function (event) { 
     this.off(document, "mousemove", videojs.bind(this, this.onMouseMove), false); 
     this.off(document, "mouseup", videojs.bind(this, this.onMouseUp), false); 
     this.off(document, "touchmove", videojs.bind(this, this.onMouseMove), false); 
     this.off(document, "touchend", videojs.bind(this, this.onMouseUp), false); 

    }; 

    videojsSeekRSBar.prototype.onMouseMove = function (event) { 
     var left = this.calculateDistance(event); 

     if (this.rs.left.pressed) 
      this.setPosition(0, left); 
     else if (this.rs.right.pressed) 
      this.setPosition(1, left); 

     //Fix a problem with the presition in the display time 
     var ctd = this.player_.controlBar.currentTimeDisplay; 
     ctd.contentEl_.innerHTML = '<span class="vjs-control-text">' + ctd.localize('Current Time') + '</span>' + videojsFormatTime(this.rs._seconds(left), this.player_.duration()); 

     // Trigger slider change 
     if (this.rs.left.pressed || this.rs.right.pressed) { 
      this.rs._triggerSliderChange(); 
     } 
    }; 

    videojsSeekRSBar.prototype.setPosition = function (index, left, writeControlTime) { 
     var writeControlTime = typeof writeControlTime != 'undefined' ? writeControlTime : true; 
     //index = 0 for left side, index = 1 for right side 
     var index = index || 0; 

     // Position shouldn't change when handle is locked 
     if (this.rs.options.locked) 
      return false; 

     // Check for invalid position 
     if (isNaN(left)) 
      return false; 

     // Check index between 0 and 1 
     if (!(index === 0 || index === 1)) 
      return false; 

     // Alias 
     var ObjLeft = this.rs.left.el_, 
      ObjRight = this.rs.right.el_, 
      Obj = this.rs[index === 0 ? 'left' : 'right'].el_, 
      tpr = this.rs.tpr.el_, 
      tpl = this.rs.tpl.el_, 
      bar = this.rs.bar, 
      ctp = this.rs[index === 0 ? 'ctpl' : 'ctpr'].el_; 

     //Check if left arrow is passing the right arrow 
     if ((index === 0 ? bar.updateLeft(left) : bar.updateRight(left))) { 
      Obj.style.left = (left * 100) + '%'; 
      index === 0 ? bar.updateLeft(left) : bar.updateRight(left); 

      this.rs[index === 0 ? 'start' : 'end'] = this.rs._seconds(left); 

      //Fix the problem when you press the button and the two arrow are underhand 
      //left.zIndex = 10 and right.zIndex=20. This is always less in this case: 
      if (index === 0) { 
       if ((left) >= 0.9) 
        ObjLeft.style.zIndex = 25; 
       else 
        ObjLeft.style.zIndex = 10; 
      } 

      //-- Panel 
      var TimeText = videojsFormatTime(this.rs._seconds(left)), 
       tplTextLegth = tpl.children[0].innerHTML.length; 
      var MaxP, MinP, MaxDisP; 
      if (tplTextLegth <= 4) //0:00 
       MaxDisP = this.player_.isFullScreen ? 3.25 : 6.5; 
      else if (tplTextLegth <= 5)//00:00 
       MaxDisP = this.player_.isFullScreen ? 4 : 8; 
      else//0:00:00 
       MaxDisP = this.player_.isFullScreen ? 5 : 10; 
      if (TimeText.length <= 4) { //0:00 
       MaxP = this.player_.isFullScreen ? 97 : 93; 
       MinP = this.player_.isFullScreen ? 0.1 : 0.5; 
      } else if (TimeText.length <= 5) {//00:00 
       MaxP = this.player_.isFullScreen ? 96 : 92; 
       MinP = this.player_.isFullScreen ? 0.1 : 0.5; 
      } else {//0:00:00 
       MaxP = this.player_.isFullScreen ? 95 : 91; 
       MinP = this.player_.isFullScreen ? 0.1 : 0.5; 
      } 

      if (index === 0) { 
       tpl.style.left = Math.max(MinP, Math.min(MaxP, (left * 100 - MaxDisP/2))) + '%'; 

       if ((tpr.style.left.replace("%", "") - tpl.style.left.replace("%", "")) <= MaxDisP) 
        tpl.style.left = Math.max(MinP, Math.min(MaxP, tpr.style.left.replace("%", "") - MaxDisP)) + '%'; 
       tpl.children[0].innerHTML = TimeText; 
      } else { 
       tpr.style.left = Math.max(MinP, Math.min(MaxP, (left * 100 - MaxDisP/2))) + '%'; 

       if (((tpr.style.left.replace("%", "") || 100) - tpl.style.left.replace("%", "")) <= MaxDisP) 
        tpr.style.left = Math.max(MinP, Math.min(MaxP, tpl.style.left.replace("%", "") - 0 + MaxDisP)) + '%'; 
       tpr.children[0].innerHTML = TimeText; 
      } 
      //-- Control Time 
      if (writeControlTime) { 
       var time = TimeText.split(":"), 
        h, m, s; 
       if (time.length == 2) { 
        h = 0; 
        m = time[0]; 
        s = time[1]; 
       } else { 
        h = time[0]; 
        m = time[1]; 
        s = time[2]; 
       } 
       ctp.children[0].value = h; 
       ctp.children[1].value = m; 
       ctp.children[2].value = s; 
      } 
     } 
     return true; 
    }; 

    videojs.registerComponent('SeekRSBar', videojsSeekRSBar); 


    /** 
    * This is the bar with the selection of the RangeSlider 
    * @param {videojs.Player|Object} player 
    * @param {Object=} options 
    * @constructor 
    */ 
    var videojsSelectionBar = videojs.extend(videojsComponent, { 
     /** @constructor */ 
     constructor: function (player, options) { 
      videojsComponent.call(this, player, options); 
      this.on('mouseup', this.onMouseUp); 
      this.on('touchend', this.onMouseUp); 
      this.fired = false; 
     } 
    }); 

    videojsSelectionBar.prototype.init_ = function() { 
     this.rs = this.player_.rangeslider; 
    }; 

    videojsSelectionBar.prototype.createEl = function() { 
     return videojsComponent.prototype.createEl.call(this, 'div', { 
      className: 'vjs-selectionbar-RS' 
     }); 
    }; 



    videojsControlTimePanelRight.prototype.init_ = function() { 
     this.rs = this.player_.rangeslider; 
     this.timeOld = {}; 
    }; 

    videojsControlTimePanelRight.prototype.createEl = function() { 
     return videojsComponent.prototype.createEl.call(this, 'div', { 
      className: 'vjs-controltimepanel-right-RS', 
      innerHTML: 'End: <input type="text" id="controltimepanel" maxlength="2" value="00"/>:<input type="text" id="controltimepanel" maxlength="2" value="00"/>:<input type="text" id="controltimepanel" maxlength="2" value="00"/>' 
     }); 
    }; 

    videojsControlTimePanelRight.prototype.onKeyDown = function (event) { 
     this.timeOld[0] = this.el_.children[0].value; 
     this.timeOld[1] = this.el_.children[1].value; 
     this.timeOld[2] = this.el_.children[2].value; 
    }; 

    videojsControlTimePanelRight.prototype.onKeyUp = function (event) { 
     this.rs._checkControlTime(1, this.el_.children, this.timeOld); 
    }; 

    videojs.registerComponent('ControlTimePanelRight', videojsControlTimePanelRight); 
})(); 

であり、これはrangesliderは、それが示して毎回どのように見えるかであります私は

video.currentTime 

Bを使用

enter image description here

答えて

0

アップあなたが使用している範囲のライダーのように見える

e.currentPoint 
+2

あなたの投稿に署名を入れないでください。あなたはあなたのプロフィールにそのものを入れることができます – NathanOliver

+1

[署名](https://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be-removed-from-posts)を使わないでください)、特にリンクを含むものではありません。彼らは迷惑メールとして認識される可能性があります。 – Glorfindel

関連する問題